在创建新实例时,python中的类变量是否会再次声明?

2024-09-28 23:32:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在练习以下代码:

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()

输出[12]:0

在[13]中:p3.getIdNum()

出[13]:2

我读了这篇文章,在这里检查了所有优秀的答案: Static class variables in Python

在创建第一个实例p1时,我看到nextIdNum被分配到0。 我觉得奇怪的是,为什么p2和p3不能再次将nextIdNum绑定到0? 在我的想象中,一旦创建了一个类而不调用方法,就应该将类变量重新赋值为0。你知道吗

我错过什么了吗?你知道吗

顺便说一下,我也在这里浏览了教程: https://docs.python.org/3.6/tutorial/classes.html#class-objects

然而,恐怕它并没有给出答案:(


Tags: 实例答案nameselfinitdefclassperson
2条回答

class语句是对type的单个调用的包装器。对主体中的语句求值,然后将其添加到传递给typedict。你知道吗

你的大致相当于

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

您可以看到,在创建MITPerson的任何实例之前,nextIdNum立即被初始化为0,就像__init__getIdNum。你知道吗


创建实例时,将执行以下步骤:

  1. MITPerson('Mark Guttag')解析为type.__call__(MITPerson, 'Mark Guttag')。你知道吗
  2. __call__调用MITPerson.__new__('Mark Guttag'),这将创建MITPerson的新实例。你知道吗
  3. 新值被传递给MITPerson.__init__,此时在递增类变量之前使用当前值MITPerson.nextIdNum。你知道吗
  4. 一旦__init__返回,__new__返回该值,此时它被赋值给p1。你知道吗

请注意,class语句体中的所有代码都不会再次执行,尽管其中定义的函数__init__没有执行。你知道吗

I saw that nextIdNum is assigned to 0 when the first instance p1 is created.

这是错误的。nextIdNum在定义类时被赋值为0。你知道吗

相关问题 更多 >