python属性查找顺序为:数据描述符>实例__dict__>类及mro继承链>非数据描述符;该顺序实时生效,动态修改类或实例属性立即影响后续查找。

Python中属性查找遵循明确的顺序,理解这个机制对掌握面向对象编程至关重要。核心原则是:先实例、再类、最后父类(MRO顺序),且数据描述符优先于实例字典。
实例字典优先:__dict__中的属性最先被找到
当访问一个实例属性时,Python首先检查该实例的__dict__。如果存在同名键,直接返回其值,不会继续向上查找。
- 例如:
obj.x = 10会把'x': 10写入obj.__dict__ - 即使类中也定义了
x(如类变量或方法),只要实例字典里有x,就用实例的值 - 删除实例属性后(
del obj.x),查找才会落到类上
类及继承链:按MRO顺序搜索类属性与方法
若实例字典未命中,Python按方法解析顺序(MRO)从当前类开始逐级向上查找。MRO可通过ClassName.mro()查看,通常是C3线性化结果。
- 类变量、普通方法、类方法、静态方法都属于这一层查找范围
- 子类重写父类属性时,子类版本会被优先选中(因MRO中子类在前)
- 注意:
@property和描述符属于另一套规则,不在此列
描述符机制:数据描述符拥有最高优先级
如果类中定义了同时具备__get__和__set__方法的描述符(如@property、classmethod),它会在实例字典之前被触发——这是唯一能“插队”的情况。
立即学习“Python免费学习笔记(深入)”;
- 数据描述符(有
__set__) > 实例字典 > 非数据描述符(只有__get__) - 典型例子:
@property修饰的属性,即使实例__dict__里有同名key,也会调用getter -
__slots__影响实例字典结构,但不改变查找顺序逻辑
动态修改的影响:运行时变更类或实例会影响查找结果
Python的属性查找是实时的,没有缓存。修改类属性、给实例新增属性、甚至替换整个类,都会立即反映在后续查找中。
- 给实例动态添加属性:
obj.new_attr = 'ok'→ 下次访问走实例字典 - 修改类变量:
MyClass.count = 99→ 所有未覆盖该属性的实例读取到新值 - 替换类的方法:
MyClass.method = new_func→ 已有实例也会使用新函数(因方法查找走类)






