cloudstack-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Will Stevens <williamstev...@gmail.com>
Subject Re: Python Question (with regards to Marvin)
Date Sun, 01 May 2016 11:43:28 GMT
Yep. Looking like there is a bug in that file. Thanks for testing. :)
On May 1, 2016 1:40 AM, "Tutkowski, Mike" <Mike.Tutkowski@netapp.com> wrote:

> Here are my tests (run from http://ideone.com/).
>
> The short story is that having multiple methods with the same name (even
> if one is an instance method and one is a class method) should probably not
> be done.
>
> If you try to invoke the instance method (ex. test.run()), the last method
> by that name in the source file is invoked (which could be the class
> method). If the number of parameters don't match, that's an error.
>
> If you try to invoke the class method (ex. Test.run()), the last method by
> that name in the source file is invoked. If this is not a class method or
> if the number of parameters don't match, that's an error.
>
> class Test:
>     @classmethod
>     def run(cls):
>         print "class hi"
>
>     def run(self):
>         print "instance hi"
>
> test = Test()
>
> test.run()
>
> What gets printed:
> instance hi
>
> class Test:
>     def run(self):
>         print "instance hi"
>
>     @classmethod
>     def run(cls):
>         print "class hi"
>
> test = Test()
>
> test.run()
>
> What gets printed:
> class hi
>
> class Test:
>     @classmethod
>     def run(cls):
>         print "class hi"
>
>     def run(self):
>         print "instance hi"
>
> # test = Test()
>
> Test.run()
>
> Runtime error
>
> class Test:
>     @classmethod
>     def run(cls):
>         print "class hi"
>
> # test = Test()
>
> Test.run()
>
> What gets printed:
> class hi
>
> class Test:
>     def run(self):
>         print "instance hi"
>
>     @classmethod
>     def run(cls):
>         print "class hi"
>
> # test = Test()
>
> Test.run()
>
> What gets printed:
> class hi
>
> class Test:
>     @classmethod
>     def run(cls):
>         print "class hi"
>
> # test = Test()
>
> Test.run()
>
> What gets printed:
> class hi
> ________________________________________
> From: Tutkowski, Mike
> Sent: Saturday, April 30, 2016 6:58 PM
> To: dev@cloudstack.apache.org
> Subject: Re: Python Question (with regards to Marvin)
>
> I can play around with it later tonight. I'm not home at the moment.
>
> When I did invoke it as Test.run(), it invoked the class method (the class
> method was listed after the instance method for that test, so I wasn't
> surprised that the class method did, in fact, get executed there).
>
> What I did not try was to list the class method first, then list the
> instance method, and then try to invoke the class method.
>
> As mentioned in my prior e-mail, when I did try to invoke the instance
> version of run, it was only successful if the instance version was the
> second one declared in the file. If the class method was declared second,
> then it was invoked even when I was trying to invoke the instance one.
>
> > On Apr 30, 2016, at 6:06 PM, Will Stevens <williamstevens@gmail.com>
> wrote:
> >
> > That's strange. That means the @classmethod decorator is not working. You
> > should have gotten the instance method in both cases.
> >
> > What if you don't instantiate Test and only do the following.
> >
> > Test.run()
> >
> > In both cases.
> > On Apr 30, 2016 6:04 PM, "Tutkowski, Mike" <Mike.Tutkowski@netapp.com>
> > wrote:
> >
> >> I ran this with an online Python tool and it calls the class method:
> >>
> >> 1       class Test:
> >> 2         def run(self):
> >> 3             print 'instance hi'
> >> 4
> >> 5         @classmethod
> >> 6         def run(cls):
> >> 7             print 'class hi'
> >> 8
> >> 9       test = Test()
> >> 10
> >> 11      test.run()
> >>
> >> If I reverse the order of the methods, the instance method is invoked:
> >>
> >> 1       class Test:
> >> 2         @classmethod
> >> 3         def run(cls):
> >> 4             print 'class hi'
> >> 5
> >> 6         def run(self):
> >> 7             print 'instance hi'
> >> 8
> >> 9       test = Test()
> >> 10
> >> 11      test.run()
> >>
> >> As I suspected, I think this means we have a problem in base.py.
> >> ________________________________________
> >> From: Will Stevens <williamstevens@gmail.com>
> >> Sent: Saturday, April 30, 2016 1:46 PM
> >> To: dev@cloudstack.apache.org
> >> Subject: Re: Python Question (with regards to Marvin)
> >>
> >> I am on my phone so I have not been able to research this for you. I
> think
> >> you are right for the most part.  Instead of multiple methods, python
> kind
> >> of fakes overloading by being to have named function arguments which can
> >> have default values, so you can call the method with a dynamic number of
> >> arguments making it appear like you are overloading, but you are
> actually
> >> calling the same function.
> >>
> >> I think in this case the two methods are actually in different scopes
> (even
> >> though they are next to each other).  The decorator actually wraps the
> >> method, so I believe in the actual runtime the to methods are in
> different
> >> scopes.
> >>
> >> I would have to look into this more to know for sure. I am taking a few
> >> minute break from building garden boxes right now. :)
> >> On Apr 30, 2016 3:31 PM, "Tutkowski, Mike" <Mike.Tutkowski@netapp.com>
> >> wrote:
> >>
> >>> Will - You can override a method in Python, but can you overload it?
> >>
> http://stackoverflow.com/questions/10202938/how-do-i-use-method-overloading-in-python
> >>>
> >>>>> On Apr 30, 2016, at 6:23 AM, Will Stevens <williamstevens@gmail.com>
> >>>> wrote:
> >>>>
> >>>> Here is a pretty good explanation.
> >>
> http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python
> >>>>
> >>>> I am guessing that both exist because the function is called both with
> >> a
> >>>> host instance and with the class itself.
> >>>>
> >>>> Class instance example: `h.enableMaintenance(client)`
> >>>>
> >>>> Class example: `Host.enableMaintenance(client, 1)`
> >>>>
> >>>> In both cases the first parameter is implicitly `h` and `Host`
> >>>> respectively.
> >>>>
> >>>> I am not sure why we need both (because I am not familiar with how
> this
> >>>> code is called), but method overloading is definitely valid in python.
> >>>>
> >>>> On Apr 30, 2016 1:08 AM, "Tutkowski, Mike" <Mike.Tutkowski@netapp.com
> >
> >>>> wrote:
> >>>>>
> >>>>> Hi everyone,
> >>>>>
> >>>>>
> >>>>> I received an error when trying to invoke the instance version of
> >>>> enableMaintenance (below).
> >>>>>
> >>>>>
> >>>>> 'TypeError: enableMaintenance() takes exactly 3 arguments (2
> >> given)\n']
> >>>>>
> >>>>>
> >>>>> I looked at base.py and it has the following with regards to
> >> maintenance
> >>>> mode for hosts:
> >>>>>
> >>>>>
> >>>>>   def enableMaintenance(self, apiclient):
> >>>>>
> >>>>>       """enables maintenance mode Host"""
> >>>>>
> >>>>>
> >>>>>       cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
> >>>>>
> >>>>>       cmd.id = self.id
> >>>>>
> >>>>>       return apiclient.prepareHostForMaintenance(cmd)
> >>>>>
> >>>>>
> >>>>>   @classmethod
> >>>>>
> >>>>>   def enableMaintenance(cls, apiclient, id):
> >>>>>
> >>>>>       """enables maintenance mode Host"""
> >>>>>
> >>>>>
> >>>>>       cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
> >>>>>
> >>>>>       cmd.id = id
> >>>>>
> >>>>>       return apiclient.prepareHostForMaintenance(cmd)
> >>>>>
> >>>>>
> >>>>> Now, I definitely have a lot more Java experience than Python, but
-
> >> as
> >>>> far as I know - having two methods with the same name such as this
> >> (even
> >>> if
> >>>> one is an instance method and the other is a class method) is not
> >> really
> >>>> "permitted" in Python.
> >>>>>
> >>>>>
> >>>>> I mean, technically it's permitted, but the second one will override
> >> the
> >>>> first one.
> >>>>>
> >>>>>
> >>>>> Can any of our Python people comment on this?
> >>>>>
> >>>>>
> >>>>> I was thinking I'd remove the class method (assuming my knowledge
> here
> >>>> regarding this topic is correct).
> >>>>>
> >>>>>
> >>>>> Thanks!
> >>>>>
> >>>>> Mike
> >>>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message