我正在练习以下代码:
class MITPerson(Person): # a subclass of class Person
nextIdNum = 0 # identification number
def __init__(self, name):
Person.__init__(self, name)
self.idNum = MITPerson.nextIdNum
MITPerson.nextIdNum += 1
def getIdNum(self):
return self.idNum
作为参考,这里是超类:
class Person(object): # superclass
def __init__(self, name):
"""Create a person"""
self.name = name
我认为自从我尝试以下实例后,我已经知道了这个问题的答案:
p1 = MITPerson('Mark Guttag')
p2 = MITPerson('Billy Bob Beaver')
p3 = MITPerson('Billy Bob Beaver')
当我在控制台中键入这些内容时,这并不奇怪:
在[12]中:p1.getIdNum()
Out [12]:0
在[13]中:p3.getIdNum()
Out [13]:2
我已阅读此帖并检查了所有优秀的答案: Static class variables in Python
我看到在创建第一个实例p1时,nextIdNum被赋值为0。 我觉得奇怪的是,为什么p2和p3也不能再次将nextIdNum绑定到0? 在我的想象中,一旦创建了一个类MITPerson而没有调用该方法,就应该将类变量重新赋值为0。
我错过了什么吗?
顺便说一句,我也在这里阅读教程: https://docs.python.org/3.6/tutorial/classes.html#class-objects
然而,我担心它没有给出答案:(
答案 0 :(得分:9)
我看到在创建第一个实例p1时,nextIdNum被赋值为0。
这是错误的。在定义类时,nextIdNum
被赋值为0。
答案 1 :(得分:2)
class
语句是对type
的单个调用的一种包装。评估正文中的语句,然后将其添加到传递给dict
的{{1}}。
你的大致相当于
type
您可以看到def _init_(self, name):
Person.__init__(self, name)
self.idNum = MITPerson.nextIdNum
MITPerson.nextIDNum += 1
def _getIdNum(self):
return self.idNum
MITPerson = type(
'MITPerson',
(Person,),
{
'__init__': _init,
'getIdNum': _getIdNum,
'nextIdNum': 0
}
)
del _init, _getIdNum
在创建nextIdNum
的任何实例之前立即初始化为0,就像MITPerson
和__init__
一样。
创建实例时,会执行以下步骤:
getIdNum
解析为MITPerson('Mark Guttag')
。type.__call__(MITPerson, 'Mark Guttag')
调用__call__
,这会创建MITPerson.__new__('Mark Guttag')
的新实例。MITPerson
,此时在递增类变量之前使用MITPerson.__init__
的当前值。MITPerson.nextIdNum
返回后,__init__
会返回该值,此时会将其分配给__new__
。请注意,p1
语句正文中的代码不会再次执行,尽管其中定义的函数class
是。