Python:变量的新实例未在类的新实例中创建

标签 python inheritance initialization

<分区>

我发现了奇怪的 Python 行为(或者我可能不明白属性的继承和/或默认值是如何工作的)。

对于给定的代码

class A(object):
    def __init__(self, s):
        self.s = s
        print "in init", self.s

class B(A):
    def __init__(self, s = set()):
        super(B, self).__init__(s)
        print "after super", self.s
        self.s.add('foo')
        print '--------------'

if __name__ == "__main__":
    a = B()
    b = B()

我得到以下输出:

in init set([])
after super set([])
--------------
in init set(['foo']) # Why it has value set in other object?!
after super set(['foo'])
--------------

当然,期望的行为是用空集初始化第二个对象 (b) 中的 self.s,但由于未知原因,它从前一个对象获取状态。为什么会这样?如何获得期望的行为?

谢谢!

最佳答案

您已落入可变默认参数陷阱。您在 B 的 __init__ 中指定为默认值的 set() 与将传递给您创建的每个新 B 的对象相同。将其放入 self 并不会生成新副本,它只会创建对同一对象的引用。

你可能想在每个新对象中制作一个副本,所以明确地这样做:

class A(object):
    def __init__(self, s):
        self.s = copy.copy(s)

关于Python:变量的新实例未在类的新实例中创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15343476/

相关文章:

python - 在 Python 中遍历字典或列表

c++ - 来自模板参数的继承层次

java - 为什么拒绝在静态 block 内的 try-catch block 中分配 final 字段?

c++ - 您将如何使用 C++11 初始化函数结果的 const vector ?

Python,如何跟踪全局变量

python - 退出 : scrapy (exit status 0; not expected)

python - 如何在使用运算符时将过滤器与 itemgetter 一起使用?

c++ - 为什么基类枚举不被继承?

python - 继承和修改 __init__() 方法

c - C 中未初始化局部变量的默认值