我对下面的Python行为感到困惑。为什么第二个和第三个实例(b
,c
),i
的属性是类属性i
,但a
的行为有所不同?
In [47]: class Foo:
...: i=0
...:
In [48]: a = Foo()
In [49]: a.i = 1
In [50]: a.i
Out[50]: 1
In [51]: Foo.i
Out[51]: 0
In [52]: b = Foo()
In [53]: b.i
Out[53]: 0
In [54]: Foo.i is b.i
Out[54]: True
In [55]: Foo.i is a.i
Out[55]: False
In [56]: c = Foo()
In [57]: Foo.i is c.i
Out[57]: True
答案 0 :(得分:6)
这里发生了什么。当你这样做时:
a.i = 1
您创建一个名为 shadows class属性的实例变量。但是,class属性仍然存在:
>>> class Foo:
... i = 0
...
>>> a = Foo()
>>> Foo.i
0
>>> a.i = 69
>>> a.i
69
>>> a.__class__.i
0
>>> del a.i # deletes the instance attribute, resolving lookup on class
>>> a.i
0
要查看实例命名空间中的内容,请查看实例dict:
>>> a = Foo()
>>> a.__dict__
{}
>>> a.i = 1
>>> a.__dict__
{'i': 1}
答案 1 :(得分:0)
a.i = 1
不会按预期更改Foo.i
。它更确定了a
的实例成员。很明显,如果您看到a.__dict__
和b.__dict__
。
In [11]: a.__dict__
Out[11]: {'i': 1}
In [13]: b.__dict__
Out[13]: {}
如果您想真正更改类成员变量,则应使用Foo.i = 1
。这将影响所有Foo
个实例。同样,在Foo.__dict__
上非常清楚。
In [17]: Foo.__dict__
Out[17]:
mappingproxy({'__dict__': <attribute '__dict__' of 'Foo' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'Foo' objects>,
'i': 0})