2016-08-19 65 views
2

我不明白以下示例中的差异。有一次,一个类的实例可以改变另一个实例的类变量,而另一次它不能?类变量:“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的危机:假

为什么这不是在这个例子中工作?

+5

这是相同的旧的“可变与不变”的问题,我们得到了一天(加上第二个原因的5倍,为什么它不以这种方式工作),它会得到5 upvotes,因为它涉及类?恭喜,我对SO社区失去了所有的信心。 –

+0

myList是类变量并且是可变的 – FujiApple

+0

请参阅[python文档](https://docs.python.org/3.5/tutorial/classes.html#class-and-instance-variables),它具有几乎完全相同的示例。 –

回答

6

在第一情况下,存在在加方法没有分配:

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