Python类变量int vs array

mca*_*mac 6 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    (['foo', 1])
y = Foo()
print y.a, y.n    (['foo', 0])
y.bar()
print y.a, y.n    (['foo', 'foo'], 1)
Run Code Online (Sandbox Code Playgroud)

Sea*_*ira 5

你是对的 - 在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    
Run Code Online (Sandbox Code Playgroud)

换句话说,当您执行self.a.append('some value')解释a器时,通过名称从内存中提取Foo,然后改变Foo.a指向的列表.

另一方面,当你做self.n += 1翻译时:

  • 获取nFoo(因为它无法找到nself)
  • 创建一个新值 n + 1
  • 存储在该属性的新值nself