类变量:"类列表"vs"类布尔"

uit*_*400 2 python instance-variables

我不明白以下示例中的区别.有一次类的一个实例可以改变另一个实例的类变量,而另一个实例却不能?

例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
Run Code Online (Sandbox Code Playgroud)

输出:

x的mylist:[1]

你的mylist:[1]

因此,这里的实例xA是能够访问和修改类属性mylist,这也是该实例的属性yA.

例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
Run Code Online (Sandbox Code Playgroud)

bankX的危机:是的

bankY的危机:错误

为什么这个例子不起作用?

Łuk*_*ski 6

在第一种情况下,add方法中没有赋值:

def add(self):
    self.mylist.append(1)  # NOT self.mylist = something
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,有一项任务:

def bankrupt(self) :
    self.crisis = True  # self.crisis = something
Run Code Online (Sandbox Code Playgroud)

当在实例上设置属性时,它总是仅在特定实例上设置(它被放到实例的__dict__属性中).班级__dict__不受影响.

在第一种情况下,没有任何分配,因此适用标准查找规则.由于__dict__实例属性中没有"mylist" ,因此它会回退到类__dict__.

在存储的add mutates值中执行的操作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!
Run Code Online (Sandbox Code Playgroud)