>>> class a:
... b=5
... def __init__(self,x,y):
... self.x=x
... self.y=y
...
>>> p=a(5,6)
>>> q=a(5,6)
>>> a.b
5
>>> a.b+=1
>>> p.b
6
>>> q.b
6
>>> q.b-=1
>>> q.b
5
>>> p.b
6
>>> a.b
6
如您所见,通过实例的方法更改类变量时,类变量和其他实例的类变量不会反射(reflect)相同的情况。为什么会这样?
因为 q.b -= 1
创建了一个名为 b
的实例变量,请查看您的 __dict__
:
q.__dict__
{'b': 4, 'x': 5, 'y': 6}
p.__dict__
{'x': 5, 'y': 6}
q.b
与 a.b
不同,您在赋值后隐藏了 a.b
。请注意,这不是 Python 3 特有的问题,Python 2 也有同样的行为。
这在 assignment statement section 中有明确说明语言引用:
Note: If the object is a class instance and the attribute reference occurs on both sides of the assignment operator, the RHS expression, a.x
can access either an instance attribute or (if no instance attribute exists) a class attribute. The LHS target a.x
is always set as an instance attribute, creating it if necessary. Thus, the two occurrences of a.x
do not necessarily refer to the same attribute: if the RHS expression refers to a class attribute, the LHS creates a new instance attribute as the target of the assignment:
class Cls:
x = 3 # class variable
inst = Cls()
inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3
This description does not necessarily apply to descriptor attributes, such as properties created with property()
.