继承+类成员

2024-04-19 06:58:13 发布

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

我从Python开始,遇到了这种奇怪的行为(至少对我来说):

class Parent:
    myStr = ""
    myInt = 0
    myDict = {}
    ....

class ChildA:
    ...
    def ...():
        self.myDict.<something>(...)
        print self.myStr
    ...

class ChildB:
    ...
    def ...():
        self.myDict.<something>(...)
        print self.myStr
    ...

根据我的理解,ChildA和ChildB的实例都应该有自己的词典。但事实证明,他们“共享”了字典。为了修复它,我需要设置自我.myDict={}在父构造函数中。另一方面,myStr和myInt似乎有它们的预期值。为什么会这样?你知道吗


Tags: 实例self字典defmydictsomethingclass词典
3条回答

这是因为在类级别绑定的名称属于类,而不是任何实例。因此,所有myDict都是相同的dict。由于dict实例是可变的,因此通过一个类/实例引用所做的更改将显示在所有dict中。字符串和数字是不可变的,因此当通过子类或实例进行赋值时,它们是反弹的。你知道吗

myDict是类级的,因此当Python查看实例却没有找到它时,它会向上搜索继承树,直到找到为止。如果将名称myDict重新绑定到实例中的任何位置,那么实例将拥有自己的版本。你知道吗

当使用可变对象(如dictlist等)时,这种行为很容易看到,但对于不可变对象(如strinttuple等)则更难观察到,因为要“更改”不可变对象的值,必须重新绑定名称--类似于:

class Foo(object):
    collection = list()
    number = 9
    def change_collection(self, new_member):
        self.collection.append(new_member)
    def change_number(self, new_number):
        self.number = new_number

a = Foo()
b = Foo()
a.change_collection('howdy!')
b.change_number(11)
print a.collection, b.collection     # ['howdy!]  ['howdy!']
print a.number, b.number             # 9  11
print a.collection is b.collection   # True
print a.number is b.number           # False

这是因为在级别设置myDict会将它绑定到类,而不是类的实例(即,所有实例将共享相同的myDict)。你知道吗

相关问题 更多 >