I am a beginner in Python, and using Lutz's book to understand classmethod
, staticmethod
and instancemethod
. The objective of this code is to understand the difference among cls
, self
, and direct Class call (Spam1.numInstances
) by counting number of instances created.
Here's an example derived from the book. I am unsure why parent class (Spam1
) attribute (numInstances
) doesn't increment when called through Sub1
and Other1
, which are child classes.
Here's my code:
class Spam1:
numInstances = 0
def count(cls):
cls.numInstances += 1
print("In count -> number of instances: cls, Spam", cls.numInstances, Spam1.numInstances)
def __init__(self):
print("-----")
print("In init, before -> number of instances: self, Spam",self.numInstances,Spam1.numInstances )
self.count()
print("In init, after -> number of instances: self, Spam",self.numInstances,Spam1.numInstances )
print("-----")
count=classmethod(count)
class Sub1(Spam1):
numInstances = 0
class Other1(Spam1):
pass
a=Spam1() #Output after increment: 1,1,1 (self, cls, Spam1)
b=Spam1() #Output after increment: 2,2,2 (self, cls, Spam1)
c=Spam1() #Output after increment: 3,3,3 (self, cls, Spam1)
d=Sub1() #Output after increment: 1,1,3 (self, cls, Spam1)
e=Sub1() #Output after increment: 2,2,3 (self, cls, Spam1)
f=Other1() #Output after increment: 4,4,3 (self, cls, Spam1)
I have spent one day trying to debug this code, but I cannot understand how cls.numInstances
works because PyCharm would show "no reference" for cls.numInstances
in debug mode. Being frustrated, I read a few SO threads: What does cls() function do inside a class method?, What is the 'cls' variable used for in Python classes?, and Python - self, no self and cls, but I cannot understand what's going on.
Specifically, here are my questions:
a) why is it that Spam1.numInstances
doesn't increase when d
, e
, and f
are created?
Here's my attempt to answer this question:
a.i) It is my understanding that cls
is used to access class attributes. For d
and e
, self.numInstances
is used to access instance attribute, which is zero because Sub1
zeroes the value of inherited attribute numInstances
from Spam1
. cls
accesses class attribute of Sub1
, which is also the same as attribute of Sub1
class. Hence, self
and cls
values we see in the output are of Sub1
instance and class respectively. Is my understanding correct?
a.ii) f
inherits numInstances
from Spam1
. Hence, self.numInstances
and cls.numInstances
of f
take the value from Spam1
. Their value is incremented but not of Spam1
because cls
refers to Other1
and because self
refers to f
, which is the object of Other1
. Hence, Spam1
's numInstances
is never touched.
b) Is my understanding about the differences among self.numInstances
, cls.numInstances
, and Spam1.numInstances
correct? If not, can someone please explain it?
I believe that my question is very basic. I hope someone will help me out. I am lost.