Python属性查找顺序_实例与类解析

3次阅读

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

Python属性查找顺序_实例与类解析

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__方法的描述符(如@propertyclassmethod),它会在实例字典之前被触发——这是唯一能“插队”的情况。

立即学习Python免费学习笔记(深入)”;

  • 数据描述符(有__set__) > 实例字典 > 非数据描述符(只有__get__
  • 典型例子:@property修饰的属性,即使实例__dict__里有同名key,也会调用getter
  • __slots__影响实例字典结构,但不改变查找顺序逻辑

动态修改的影响:运行时变更类或实例会影响查找结果

Python的属性查找是实时的,没有缓存。修改类属性、给实例新增属性、甚至替换整个类,都会立即反映在后续查找中。

  • 给实例动态添加属性:obj.new_attr = 'ok' → 下次访问走实例字典
  • 修改类变量:MyClass.count = 99 → 所有未覆盖该属性的实例读取到新值
  • 替换类的方法:MyClass.method = new_func → 已有实例也会使用新函数(因方法查找走类)
text=ZqhQzanResources