Python类变量int vs array

Python类变量int vs array,python,class,Python,Class,我在玩Python类,并得到了下面的示例,其中两个看起来是静态类变量的变量在修改时具有不同的行为 这是怎么回事?我的第一直觉是,一些棘手的事情正在发生 class Foo: a = [] n = 0 def bar(self): self.a.append('foo') self.n += 1 x = Foo() print x.a, x.n ([] 0) x.bar() print x.a, x.n (['f

我在玩Python类,并得到了下面的示例,其中两个看起来是静态类变量的变量在修改时具有不同的行为

这是怎么回事?我的第一直觉是,一些棘手的事情正在发生

class Foo:
    a = []
    n = 0
    def bar(self):
            self.a.append('foo')
            self.n += 1

x = Foo()
print x.a, x.n    ([] 0)
x.bar()
print x.a, x.n    (['foo', 1])
y = Foo()
print y.a, y.n    (['foo', 0])
y.bar()
print y.a, y.n    (['foo', 'foo'], 1)

您是正确的-在
Foo.a
访问
self.a
的情况下,实际上访问
Foo.a
,这是在
Foo
的所有实例之间共享的。但是,当您使用
+=
更新
self.n
时,实际上是在
self
上创建了一个实例级变量,该变量会对
Foo.n
产生阴影:

>>> import dis
>>> dis.dis(Foo.bar)
  5           0 LOAD_FAST                0 (self)
              3 LOAD_ATTR                0 (a)
              6 LOAD_ATTR                1 (append)
              9 LOAD_CONST               1 ('foo')
             12 CALL_FUNCTION            1
             15 POP_TOP             

  6          16 LOAD_FAST                0 (self)
             19 DUP_TOP             
             20 LOAD_ATTR                2 (n)
             23 LOAD_CONST               2 (1)
             26 INPLACE_ADD         
             27 ROT_TWO             
             28 STORE_ATTR               2 (n)
             31 LOAD_CONST               0 (None)
             34 RETURN_VALUE    
换句话说,当您执行
self.a.append('some value')
时,解释器通过
Foo
上的名称从内存中获取
a
,然后对
Foo.a
指向的列表进行变异

另一方面,当您执行
self.n+=1
解释器时:

  • Foo
    获取
    n
    (因为它在
    self
    上找不到
    n
  • 创建一个新值
    n+1
  • 将新值存储在
    n
    on
    self

明白了。导致阴影的赋值(对我来说)在
+=
后面被混淆了。谢谢这里有一个类似的python案例