修改Python类变量为何会影响所有已创建的实例对象?
Python类变量与实例属性的查找逻辑
你遇到的现象是Python属性查找顺序的典型表现,核心逻辑如下:
- 当你访问
instance.attr时,Python会优先在实例自己的__dict__属性字典里查找对应键,如果找不到,就会去该实例所属的类的__dict__里查找,再找不到才会去父类的MRO继承链上逐层查找。 - 你从始至终都没有给任何实例的
varia属性单独赋值,所以所有实例访问varia的时候,都会直接读取所属类的ExampleClass.varia值,自然类变量修改后,所有实例读到的都是最新值。
简化测试代码的对应解释
class ExampleClass: varia = 1 class_1=ExampleClass() # 此时class_1自己的__dict__是空的,没有varia属性,你可以加一行print(class_1.__dict__)验证输出为{} ExampleClass.varia=2 # 你修改的是类的属性,没有改动过class_1的任何属性 class_2=ExampleClass() # class_2的__dict__同样是空的 print(class_1.varia) # 查找顺序:class_1.__dict__找不到varia → 去ExampleClass.__dict__找,拿到最新的2 print(class_2.varia) # 同理,拿到的也是类的varia值2
如果你想让实例保留创建时的类变量快照,你需要在实例化时显式把值赋值给实例属性,就像你处理val2的逻辑一样:
class ExampleClass: varia = 1 def __init__(self): # 显式把当前类的varia值赋值给实例自己的varia属性 self.varia = ExampleClass.varia class_1=ExampleClass() ExampleClass.varia=2 class_2=ExampleClass() print(class_1.varia) # 输出1,读的是实例自己的属性 print(class_2.varia) # 输出2,读的是自己实例化时存的属性
第一段代码的补充说明
你第一个代码里在__init__中修改的是ExampleClass.varia,也就是类本身的属性,所有没单独赋值varia的实例读到的自然都是最后一次修改的3,只有你显式赋值给self.val2的实例属性,才是每个实例独有的,不会互相影响。
内容的提问来源于stack exchange,提问作者BertHobe
相关产品推荐
相关产品推荐

