我正在使用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)
答案 0 :(得分: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
的实例级变量:
self.a.append('some value')
换句话说,当你执行a
时,解释器会通过Foo
上的名称从内存中提取Foo.a
,然后改变self.n += 1
指向的列表。
另一方面,当你n
翻译时:
Foo
获取n
(因为self
上无法找到n + 1
)n
self