Python类变量int vs数组
问题内容:
我正在研究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')
此操作时,解释a
器将通过名称on从内存中获取数据Foo
,然后对Foo.a
指向的列表进行变异。
另一方面,当您执行self.n += 1
口译员时:
- 取
n
从Foo
(因为它无法找到n
上self
) - 创建一个新的价值
n + 1
- 将新值存储在的属性
n
中self