类变量:“class list”vs“class boolean”
问题描述:
我不明白以下示例中的差异。有一次,一个类的实例可以改变另一个实例的类变量,而另一次它不能?类变量:“class list”vs“class boolean”
实施例1:
class MyClass(object):
mylist = []
def add(self):
self.mylist.append(1)
x = MyClass()
y = MyClass()
x.add()
print "x's mylist: ",x.mylist
print "y's mylist: ",y.mylist
输出:
X的MYLIST:[1]
ÿ的MYLIST:[1]
因此,这里的实例x
的类A
能够访问和修改类属性e mylist
,这也是A
的实例y
的属性。
例2:
class MyBank(object):
crisis = False
def bankrupt(self) :
self.crisis = True
bankX = MyBank()
bankY = MyBank()
bankX.bankrupt()
print "bankX's crisis: ",bankX.crisis
print "bankY's crisis: ",bankY.crisis
bankX的危机:真
bankY的危机:假
为什么这不是在这个例子中工作?
答
在第一情况下,存在在加方法没有分配:
def add(self):
self.mylist.append(1) # NOT self.mylist = something
在第二情况下,有一个赋值:
def bankrupt(self) :
self.crisis = True # self.crisis = something
当属性被设置在例如,它总是被设定上仅限特定实例(它被放入实例的__dict__
属性中)。 __dict__
类不受影响。
在第一种情况下没有分配,因此应用标准查找规则。由于实例的__dict__
属性中没有“mylist”,因此它会回到类__dict__
。
在add
中执行的操作变异存储在MyClass.__dict__
中的值。这就是为什么在所有情况下可以观察到变化。
考虑下面的代码片断(它可能更好地解释您的问题):
class MyClass:
x = []
x1 = MyClass()
x2 = MyClass()
x3 = MyClass()
x1.x.append(1)
print x1.x # [1]
print x2.x # [1]
print x3.x # [1]
assert x1.x is x2.x is x3.x
x3.x = "new" # now x3.x no longer refers to class attribute
print x1.x # [1]
print x2.x # [1]
print x3.x # "new"
assert x1.x is x3.x # no longer True!
+0
你知道他们为什么这样做吗? – uitty400
这是相同的旧的“可变与不变”的问题,我们得到了一天(加上第二个原因的5倍,为什么它不以这种方式工作),它会得到5 upvotes,因为它涉及类?恭喜,我对SO社区失去了所有的信心。 –
myList是类变量并且是可变的 – FujiApple
请参阅[python文档](https://docs.python.org/3.5/tutorial/classes.html#class-and-instance-variables),它具有几乎完全相同的示例。 –