2016-08-19 5 views
2

次の例の違いはわかりません。あるクラスのインスタンスが別のインスタンスのクラス変数を変更することができ、もう一度それができない場合は、クラス変数: "クラスリスト" vs "クラスブール値"

例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のマイリスト:[1]

Yのマイリスト:[1]

ので、ここでのインスタンスxクラスAは、クラス属性にアクセスして変更することができましたe mylistyのインスタンスの属性であるAです。

例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の危機:偽

なぜこれがこの例では動作しませんか? Addメソッドには割り当てがない最初のケースで

+5

はスニペット(それはもっと自分の問題を説明するかもしれない)、次の点を考慮しますそのように働く)、それはクラスに関係するだけで5つのアップボントを取得しますか?おめでとう、私はSOコミュニティのすべての信念を失ったばかりです。 –

+0

myListはクラス変数であり、変更可能です – FujiApple

+0

ほぼ同じ例を持つ[python documentation](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 

第2のケースで割り当てがある:

def bankrupt(self) : 
    self.crisis = True # self.crisis = something 

属性がインスタンスに設定されている場合、それは常にオンに設定されているが特定のインスタンスのみ(インスタンスの__dict__アトリビュートに置かれます)。クラス__dict__は影響を受けません。

最初のケースでは割り当てがないため、標準ルックアップルールが適用されます。インスタンスの__dict__属性に「mylist」がないので、クラス__dict__に戻ります。

addで実行される操作の値は、MyClass.__dict__に格納されます。そういうわけで、変化がすべての場合に観察可能です。これは、我々は1日5回(プラスそれがない理由第二の理由を得る同じ古い「不変の対可変」という質問です

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