Python3直接修改类属性是否会覆盖实例同名属性使其变为静态属性?
Python类属性与实例属性的行为差异说明
核心原理:Python属性查找规则
当你访问实例.属性名时,Python的查找优先级如下:
- 先查找实例自身的属性存储字典
__dict__中是否存在该属性,存在则直接返回对应值 - 若实例自身没有该属性,再查找实例所属类的
__dict__中是否存在该属性,存在则返回类属性的值 - 若类中也没有,则继续按照继承链向上查找父类的属性,最终找不到则抛出
AttributeError
第一个示例运行逻辑
第一段代码中init方法修改的是MemberCounter.members,也就是直接修改类本身的属性值,全程没有给任何实例绑定属于自己的members实例属性:
- 两次调用
init后,类属性MemberCounter.members被累计修改为2 - 打印
m1.members、m2.members时,两个实例自身的__dict__里没有members属性,Python自动向上查找类的members属性返回,所以得到的都是类属性的当前值2。你观察到的「同步变化」本质是你读到的本来就是同一个类属性的值,并非实例有独立的属性跟着类变化。
第二个示例运行逻辑
第二段代码中init方法执行self.members += 1,等价于self.members = self.members + 1,执行过程如下:
- 读取等号右侧的
self.members:此时实例自身没有members属性,读取到类属性members的初始值0 - 计算得到0+1=1后,执行赋值操作
self.members = 1,这一步会直接给当前实例绑定一个属于自己的members实例属性,存入实例的__dict__中 - 后续再访问该实例的
members属性时,会直接读取实例自身的属性值,不会再查找类属性
最终结果:
- 全程没有修改过类的
members属性,所以类属性值保持为0 - 两个实例各自绑定了自己的
members属性,值都是1,符合你的预期。
验证方法
你可以通过打印__dict__确认属性归属:
- 第一个示例执行后打印
print(m1.__dict__),输出为空,说明实例没有自己的members属性 - 第二个示例执行后打印
print(m1.__dict__),输出为{'members': 1},说明实例已经绑定了自己的members属性
内容的提问来源于stack exchange,提问作者Solomon
相关产品推荐
相关产品推荐

