[Tutor] Declaration order of classes... why it is important?

Mac Ryan quasipedia at gmail.com
Fri Aug 28 17:06:07 CEST 2009


On Fri, 2009-08-28 at 08:55 -0400, Dave Angel wrote:
> Mac Ryan wrote:
> > On Wed, 2009-08-26 at 21:32 -0400, Dave Angel wrote:
> >
> >   
> >> Now there are a couple of decorators that are in the standard library 
> >> that everyone should know about:    classmethod() and staticmethod().  
> >> They wrap a method in a new one (which ends up having the same name), 
> >> such that the first argument is either eaten (staticmethod), or changed 
> >> to a class (classmethod).
> >>
> >> Hope that was sufficient detail.
> >>
> >> DaveA
> >>     
> >
> > Thank you all for your answer, I read the link posted by Kent end the
> > explanations given by others, and now almost all the pieces of the
> > puzzle are falling to their place.
> >
> > The (last?) thing still escaping my understanding is the difference
> > between classmethod() and staticmethod(). I understand that both of them
> > are to make sure a method will be associated with the class rather than
> > with an instance of it (a bit like variables declared in a class but
> > outside a method), so I assume I should use them like:
> >
> > class myClass(object):
> >
> >   @staticmethod / @classmethod
> >   def method_of_class(self):
> >     pass
> >
> >   def method_of_instances(self):
> >     pass
> >
> > I am not sure I understood the difference between staticmethod end
> > classmethod, though, even if I can guess it has to do with subclassing,
> > (given classmethod go fish for the class name)... am I on the right
> > track? Any hint (or full-fledged explanation!)? :)
> >
> > [The official documentation is a bit obscure for me as it refers to C#
> > and Java, languages that I do not know.]
> >
> > Also, what is the advantage of using a method at class level rather than
> > using it at object instance (I can imagine you can save some memory by
> > not duplicating X times the same code, maybe... but what kind of designs
> > require/call for use of statc/classmethods?)
> >
> > Thank you in advance for your help,
> > Mac.
> >
> >
> >   
> I thought someone (me) had already posted examples.  The method itself 
> looks different in the three cases:
> 
> class  MyClass(object):
> 
>      def my_method1(self, arg):
>               ... do something with this particular object
> 
>      @classmethod
>       def my_class_method(cls, arg)
>                .... do something that may requires use of class, but 
> that doesn't need to know the particular object
> 
>       @staticmethod
>        def my_static_method(arg):
>                ....  do something which isn't affected at all by what 
> class it's in
> 
> self and cls parameters are named that merely by convention.  Unlike the 
> "this" of C++, C#, and Java, these names have no specific meaning to the 
> compiler. But convention is a very good thing, especially in this case.
> 
> So the first difference between static and class is that the method 
> signature must be different.  There's an extra parameter on the latter 
> that must be included.  The second difference is that a classmethod may 
> call other methods of the same class, and gets the appropriate methods 
> even if the class was subclassed.
> 
> The hint to play with is that any of these 3 may be called with an 
> object  (obj.my_class_method()), and the last two may be called with a 
> classname.
> 
> DaveA

Thank you Dave, very helpful as ever. I made a few tests and experiments
to understand better, and I feel I am understanding how it works.
Although the mechanic of this is increasingly clear, the logic behind is
still a bit obscure: here comes a silly test on which results I have
questions about

======================================================

class A(object):
  variable = 0
  @classmethod
  def cm(cls):
    cls.variable += 3
    
class B(A):
  pass
  
class C(B):
  pass
  
a = A()
b = B()
c = C()
print A.variable, a.variable
print B.variable, b.variable
print C.variable, c.variable
print '---'
a.cm()
print A.variable, a.variable
print B.variable, b.variable
print C.variable, c.variable
print '---'
b.cm()
print A.variable, a.variable
print B.variable, b.variable
print C.variable, c.variable
print '---'
c.cm()
print A.variable, a.variable
print B.variable, b.variable
print C.variable, c.variable
print '---'
a.variable = 7
A.variable = 4
print A.variable, a.variable
print B.variable, b.variable
print C.variable, c.variable
print '---'
B.variable = 'x'
print A.variable, a.variable
print B.variable, b.variable
print C.variable, c.variable

======================================================

Now, the output of this test is as follows (I manually added the numbers
on the right for reference in the remaining of the post):

0 0 # 1
0 0
0 0
---
3 3 # 2
3 3
3 3
---
3 3 # 3
6 6
6 6
---
3 3 # 4
6 6
9 9
---
4 7 # 5 
6 6
9 9
---
4 7 # 6
x x
9 9

#1 is plain obvious.

#2 came as a bit of surprise: "Ah-ah!... so the class variable is the
same for all the hierarchy of classes! I would have guessed each class
had its own variable..."

#3 and #4 are bigger surprises: "Uh? let me understand better, so... it
must be like branches... as soon as I say that B.variable is different
than its ancestors, all the descendants of B get updated... Yet, it's
strange: this very thread on the mailing list has started with me asking
about the order of declaration for classes, and I have been told that
class variables are processed as soon as the interpreter hits the class
definition... so I would have expected that C.variable would have been
initialised already and would not dynamically change when B.variable
does..."

#5 confused me: it seems that a.variable can refer to both the class
variable or a newly created object property... that sounds like a
never-ending source of bugs to me: it is me who has then to remember if
a given syntax refers to a class variable or to an object method?

#6 really make no sense to me: it seems that the class variable of C has
not been changed this time (as it did in #3)...

The points above confuse me even more about the "design purposes" of
classmethods and staticmethods...

Any help/feedback, very much appreciated.

mac.



More information about the Tutor mailing list