关于python:类变量的行为

Behavior of class variables

本问题已经有最佳答案,请猛点这里访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>> 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

如您所见,通过实例的方法更改类变量时,这一点不会反映在其他实例的类变量和类变量中。为什么会这样?


因为q.b -= 1创建了一个名为b的实例变量,所以在__dict__中查找:

1
2
3
4
5
q.__dict__
{'b': 4, 'x': 5, 'y': 6}

p.__dict__
{'x': 5, 'y': 6}

q.ba.b不同,你在任务完成后隐藏了a.b。请注意,这不是特定于Python3的问题,Python2的行为方式也相同。

这一点在语言参考的"任务说明"一节中有明确说明:

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:

1
2
3
4
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().