I would expect the following code to print 012345 but it prints 012012. Why? I would expect the calls to incr to be accessing the same variables since they are inherited from the same class but they are clearly different variables.
class a(object):
var = 0
@classmethod
def incr(cls):
print cls.var
cls.var+=1
class b(a):
def func(self):
super(b,self).incr()
class c(a):
def func(self):
super(c,self).incr()
t = a()
t1 = b()
t2 = c()
t1.func()
t1.func()
t1.func()
t2.func()
t2.func()
t2.func()
Both class
b
and classc
inherit from classa
separately, andvar
is set to 0 each time.One way to have class
c
to get the same value ofvar
in classa
as classb
does, classc
can inherit from classb
like so:There is a way to produce the sequence 012345. You have to make sure that the
var
of classa
is increased in theincr
method, even when it is called in the subclasses. To achieve this, increment bya.var += 1
, not bycls.var += 1
.As pointed out by the other answers, the
var
is also inherited tob
andc
. By usingcls.var += 1
both subclasses increase their ownvar
instead ofa
'svar
.Produces:
They are inherited from the same class, but the
cls
passed to theclassmethod
via super is the current class where the method was called from.super
accesses the base class version of the method, but thecls
for the call is the class where the super call was made.This is one of the subtle differences between doing:
and:
You can confirm this by printing the current
cls
in yourincr
method in both cases:You should never assume that all
super
does is make a method call bound to the parent class. It does a lot more.Keep in mind that when the first augmented assignment
+=
is performed, the initial value ofvar
is read from the base class (since at this point it does not exist in the dict of the subclasses). The updated value is however written to the subclass. Callingsuper
from the second subclass repeats the same behavior of reading the initialvar
value froma
.