您是正确的-在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
口译员时: