puzzlement about classmethod

F

Faheem Mitha

Hi,

Consider the following small script.

My understanding of how this works is that, conceptually, class B
holds a separate copy of variable x from class A.

Nearly everything behaves the way I would expect, except that setting
x to 12 in A using class_setx at the beginning also sets the value for
x in B. However, the converse (setting x in B using class_setx), does
not change the value in A, which I would consider to be the expected
behavior.

However, after that the two x variables appear to behave
independently. Can anyone explain to me why this is so?

Regards, Faheem Mitha.

******************************************************************
#!/usr/bin/python

class A(object):
x = 0
def class_getx(cls):
return cls.x
class_getx = classmethod(class_getx)
def class_setx(cls, _x):
cls.x = _x
class_setx = classmethod(class_setx)
def getx(self):
return type(self).x
def setx(self, _x):
type(self).x = _x

class B(A):
pass

def printx():
print "*** begin printing values of x... ***"
print "Fetching from A using class_getx gives %s"%(A.class_getx())
print "Fetching from B using class_getx gives %s"%(B.class_getx())
print "Fetching from A using instance a and getx gives %s"%(a.getx())
print "Fetching from B using instance b and getx gives %s"%(b.getx())
print "*** end printing values of x... ***"

a = A()
b = B()
printx()
print "setting x to 12 in A using class_setx"; A.class_setx(12)
printx()
print "setting x to 15 in B using class_setx"; B.class_setx(15)
printx()
print "setting x to 10 in A using class_setx"
A.class_setx(10)
printx()
print "setting x to 44 in A using instance a and setx"; a.setx(55)
printx()
print "setting x to 22 in B using instance b and setx"; b.setx(22)
printx()
 
D

Duncan Booth

Faheem said:
Nearly everything behaves the way I would expect, except that setting
x to 12 in A using class_setx at the beginning also sets the value for
x in B. However, the converse (setting x in B using class_setx), does
not change the value in A, which I would consider to be the expected
behavior.

However, after that the two x variables appear to behave
independently. Can anyone explain to me why this is so?

When you access a class variable B.x before it has been set in B then you
see the value from the base class (A.x). Once you have set a separate value
in the subclass that takes precedence.

Similarly accessing an instance variable b.x first looks in the instance
(b), then in the class (B), then in the base class or classes (here A). The
lookup stops as soon as it finds a value in any of these locations.
 
D

Dennis Lee Bieber

a = A()
b = B()
print id(A.x), id(B.x), id(a.x), id(b.x)
print "setting x to 12 in A using class_setx"; A.class_setx(12)
print id(A.x), id(B.x), id(a.x), id(b.x)
print "setting x to 15 in B using class_setx"; B.class_setx(15)
print id(A.x), id(B.x), id(a.x), id(b.x)
print "setting x to 10 in A using class_setx"; A.class_setx(10)
print id(A.x), id(B.x), id(a.x), id(b.x)
print "setting x to 44 in A using instance a and setx"; a.setx(55)
print id(A.x), id(B.x), id(a.x), id(b.x)
print "setting x to 22 in B using instance b and setx"; b.setx(22)
print id(A.x), id(B.x), id(a.x), id(b.x)

-=-=-=-
3301588 3301588 3301588 3301588
all references are /retrieving/ the same object

setting x to 12 in A using class_setx
3301444 3301444 3301444 3301444
all references are still retrieving the same object (though it is a
different same object)

setting x to 15 in B using class_setx
3301444 3301408 3301444 3301408
all references found via B are a different object than all
references found via A

setting x to 10 in A using class_setx
3301468 3301408 3301468 3301408
now the A references are to a different object

setting x to 44 in A using instance a and setx
3300928 3301408 3300928 3301408
since your "setx" was retrieving the class type, and doing a set on
that, it is identical to your class_setx in effect -- you changed the A
object reference

setting x to 22 in B using instance b and setx
3300928 3301324 3300928 3301324
same, but for B... You don't have ANY "instance" attributes in play,
they are all "class" attributes. Replace "type(self)." with just "self."
in setx and you'd see the instance references changing.
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top