python 中的 class 变量会在创建新实例时再次声明吗?
Will a class variable in python be declared again when a new instance is created?
我正在练习以下代码:
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:
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()
输出[12]: 0
在[13]中:p3.getIdNum()
输出[13]: 2
我已阅读此 post 并查看了此处的所有优秀答案:
Static class variables in Python
我看到创建第一个实例p1时,nextIdNum被赋值为0。
我觉得奇怪的是为什么p2和p3不把nextIdNum也重新绑定到0呢?
在我的想象中,一旦 class MITPerson 在不调用方法的情况下创建,class 变量应该被重新分配为 0。
我是不是漏掉了什么?
顺便说一句,我也在这里浏览了教程:
https://docs.python.org/3.6/tutorial/classes.html#class-objects
不过,恐怕没有给出答案:(
I saw that nextIdNum is assigned to 0 when the first instance p1 is created.
这是错误的。当定义 class 时,nextIdNum
被赋值为 0。
class
语句是一种对 type
的单次调用的包装。对主体中的语句进行求值,然后将其添加到传递给 type
.
的 dict
你的大致相当于
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
在创建 MITPerson
的任何实例之前立即初始化为 0,就像 __init__
和 getIdNum
.
创建实例时,会发生以下步骤:
MITPerson('Mark Guttag')
解析为 type.__call__(MITPerson, 'Mark Guttag')
。
__call__
调用 MITPerson.__new__('Mark Guttag')
,创建 MITPerson
. 的新实例
- 新值被传递给
MITPerson.__init__
,此时在递增 class 变量之前使用 MITPerson.nextIdNum
的当前值。
- 一次
__init__
returns,__new__
returns那个值,此时它被赋值给p1
.
注意none class
语句主体中的代码再次执行,尽管那里定义的函数__init__
。
我正在练习以下代码:
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:
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()
输出[12]: 0
在[13]中:p3.getIdNum()
输出[13]: 2
我已阅读此 post 并查看了此处的所有优秀答案: Static class variables in Python
我看到创建第一个实例p1时,nextIdNum被赋值为0。 我觉得奇怪的是为什么p2和p3不把nextIdNum也重新绑定到0呢? 在我的想象中,一旦 class MITPerson 在不调用方法的情况下创建,class 变量应该被重新分配为 0。
我是不是漏掉了什么?
顺便说一句,我也在这里浏览了教程: https://docs.python.org/3.6/tutorial/classes.html#class-objects
不过,恐怕没有给出答案:(
I saw that nextIdNum is assigned to 0 when the first instance p1 is created.
这是错误的。当定义 class 时,nextIdNum
被赋值为 0。
class
语句是一种对 type
的单次调用的包装。对主体中的语句进行求值,然后将其添加到传递给 type
.
dict
你的大致相当于
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
在创建 MITPerson
的任何实例之前立即初始化为 0,就像 __init__
和 getIdNum
.
创建实例时,会发生以下步骤:
MITPerson('Mark Guttag')
解析为type.__call__(MITPerson, 'Mark Guttag')
。__call__
调用MITPerson.__new__('Mark Guttag')
,创建MITPerson
. 的新实例
- 新值被传递给
MITPerson.__init__
,此时在递增 class 变量之前使用MITPerson.nextIdNum
的当前值。 - 一次
__init__
returns,__new__
returns那个值,此时它被赋值给p1
.
注意none class
语句主体中的代码再次执行,尽管那里定义的函数__init__
。