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

Mac Ryan quasipedia at gmail.com
Sat Aug 29 12:34:44 CEST 2009


On Fri, 2009-08-28 at 12:24 -0400, Dave Angel wrote:
> > 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.
> >
> >
> >   
> Great questions.  I love a person who is organized as you are.  And as 
> willing to learn.
> 
> #3 and #4 - First let me point out that these are not class variables, 
> but class attributes.   It's unfortunate that you called the attributes 
> with the label 'variable'.  I frequently make the same mistake (call it 
> sloppy mistake), but it might matter somewhere in the following 
> discussion.  A class variable is simply a "variable" which references 
> the class.  Think of it as an alias for the class.  Just like a list 
> variable is a variable which references a list.  If you do:
>      newclass = A
> 
> then you can use newclass in exactly the same way as A.     a = 
> newclass(),  print newclass.variable, etc.
> 
> A class attribute, on the other hand, is what other languages would call 
> a field of the class.  And it definitely does get initialized when the 
> class is executed.  That's important in the earlier discussion because 
> the *right-hand-side* has to be valid at that time, which is why you had 
> the forward referencing problem.  So in the following code:
> 
> n = 12
> class  A(object):
>      attr = n
> 
> n = 42
> 
> 
> the attribute A.attr is a reference to 12, not 42.  The confusion in 
> this #3 and #4 case is that when some later expression tries to use a 
> particular class attribute there are some rules for lookup.  I don't 
> know the correct terminology, but I think of this as the "." operator.  
> When I say  C.variable, the first search is in the classes dictionary.  
> If it's not found there, then it searches in the parent class' 
> dictionary, and so on.  The attribute is not copied, there's just a 
> search order when it's accessed.
> 
> #5 - It's search order again (on what I call the dot operator).  When 
> you reference  c.variable, it looks first in the dictionary for the 
> instance object c, and then if it doesn't find it, it looks in the 
> parent, which is the class.  And if it doesn't find it there, it again 
> looks in the parent, and so on.
> 
> #6 - by this time, there is a class attribute C.variable, so changing 
> B.variable has no effect    Probably the key thing that misleads people 
> is that the += operator may actually create a new attribute.  That 
> happened when you called  b.cm() and c.cm().
> 
> You might be helped by using help(B) before and after the call to 
> b.cm().  It says a lot that you might not care about, but it makes clear 
> what attribute are "defined here" versus "inherited from..."
> 
> 
> HTH
> DaveA

Well, thank you a lot for the explanation. Now it makes perfectly sense
and I am an happy man. :)

BTW, your appreciation for good learners is totally matched by my
appreciation for good teachers... thank you again! :)

Mac.



More information about the Tutor mailing list