我从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的实例应该有自己的词典。但事实证明,他们“共享”字典。要修复它,我需要在父的构造函数中设置self.myDict = {}。另一方面,myStr和myInt似乎有其预期的值。为什么会这样?
答案 0 :(得分:3)
这是因为在类级别绑定的名称属于该类,而不属于任何实例。因此,所有myDict
都是相同的词。由于dict实例是可变的,因此通过一个类/实例引用所做的更改将显示在所有实例中。字符串和数字是不可变的,因此当通过子类或实例分配时,它们会反弹。
答案 1 :(得分:3)
myDict
是类级别的,因此当Python查看实例并且找不到它时,它会搜索继承树,直到它为止。如果在实例中的任何位置重新绑定名称myDict
,则实例将具有自己的版本。
使用dict
,list
等可变对象时很容易看到此行为,但使用str
,int
等不可变对象更难以观察到,tuple
等,因为为了“改变”不可变的值,你必须重新绑定名称 - 如下所示:
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
答案 2 :(得分:2)
这是因为在类级别设置myDict
会将其绑定到类和而不是类的实例(即,所有实例将共享相同的myDict
)。
答案 3 :(得分:0)
问题的关键在于Ignacio指出,可变与不可变。这是一个完整的ASCII图解释的链接:
http://mail.python.org/pipermail/tutor/2001-February/003787.html