Python 类与实例的属性查找顺序

发布时间 - 2026-01-28 00:00:00    点击率:
Python属性查找严格遵循MRO顺序:实例__dict__ > 按MRO从__class__开始逐类__dict__查找 > object;__getattribute__为总闸门,property作为数据描述符优先于实例属性,但低于__getattribute__拦截。

Python 中属性查找的 MRO 顺序是什么

Python 查找属性时,不是先看实例再看类那么简单——它严格遵循方法解析顺序(MRO),即从实例的 __class__ 开始,沿继承链向上搜索,直到 object。这个顺序由 C3 线性化算法决定,可通过 ClassName.mro() 查看。

关键点在于:**实例属性 > 类属性 > 父类属性 > 内置基类属性**,但所有“类属性”层面的查找都走 MRO,不跳过中间类。

  • 如果实例有 __dict__ 中的同名属性,直接返回,不触发 MRO 查找
  • 如果实例没有,才从 type(instance) 开始按 MRO 元组逐个检查类的 __dict__
  • super() 的行为也依赖 MRO,不是简单找父类

为什么给实例赋值会“遮蔽”类变量

给实例设置属性(如 obj.x = 1)会在该实例的 __dict__ 中新建条目,后续对该实例访问 x 就不再进入 MRO 查找——这和“类变量被修改”是两回事。

常见误判场景:

  • 多个实例共享一个可变类属性(如 list),结果互相污染
  • 误以为 self.x = ... 是在更新类变量,实际只是绑定到当前实例
  • del obj.x 删除后,再次访问才重新触发 MRO 查找类属性

示例:

class A:
    x = []
a1, a2 = A(), A()
a1.x.append(1)
print(a2.x)  # [1] —— 共享的是同一个 list 对象

@property 和 __getattribute__ 如何介入查找流

__getattribute__ 是属性访问的总闸门,只要访问任意属性(包括 __dict____class__),它都会被调用;而 @property 是数据描述符,优先级高于实例字典中的同名属性,但低于 __getattribute__ 的显式拦截。

  • 若自定义了 __getattribute__,必须显式调用 super().__getattribute__(name) 才能触发后续 MRO 查找,否则整个链路被截断
  • @property 本质是实现了 __get__ 的描述符,属于“数据描述符”,所以比实例 __dict__ 中的同名键优先
  • 非数据描述符(如方法、@classmethod)则在实例属性未命中后才被查到

动态修改类属性时实例是否同步更新

只影响尚未在实例中设置该属性的那些对象。一旦实例执行过 obj.attr = ...,它就拥有了自己的副本,后续对类属性的修改与之无关。

  • 读取时:实例有则用实例的,没有才读类的(按 MRO)
  • 写入时:obj.attr = ... 永远写入实例 __dict__,不会修改类属性
  • 想强制更新所有实例?只能遍历已存在的实例并手动赋值,或改用 __setattr__ 拦截(慎用)

最容易被忽略的是:类属性本身是对象引用,修改其内容(如 cls.items.append(...))会影响所有共享它的实例;但重新赋值(cls.items = [])只改变类本身,不影响已有实例。


# python  # app  # 为什么  # Object  # 父类  # 继承  # Property  # append  # 对象  # 算法  # 类属  # 的是  # 自己的  # 线性化  # 是在  # 多个  # 已有  # 遍历  # 会在  # 自定义 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 网站制作报价单模板图片,小松挖机官方网站报价?  夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  Laravel Fortify是什么,和Jetstream有什么关系  制作电商网页,电商供应链怎么做?  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  Laravel Session怎么存储_Laravel Session驱动配置详解  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践  jQuery 常见小例汇总  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  Mybatis 中的insertOrUpdate操作  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  如何快速登录WAP自助建站平台?  进行网站优化必须要坚持的四大原则  如何在阿里云高效完成企业建站全流程?  如何在七牛云存储上搭建网站并设置自定义域名?  如何快速完成中国万网建站详细流程?  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  如何快速搭建高效可靠的建站解决方案?  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  如何在企业微信快速生成手机电脑官网?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  Laravel怎么判断请求类型_Laravel Request isMethod用法  Laravel怎么使用artisan命令缓存配置和视图  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  JavaScript实现Fly Bird小游戏  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  浅谈Javascript中的Label语句  怎么用AI帮你为初创公司进行市场定位分析?  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  如何快速搭建FTP站点实现文件共享?  如何在香港免费服务器上快速搭建网站?  java获取注册ip实例  Laravel如何处理文件下载请求?(Response示例)  如何快速搭建安全的FTP站点?  Linux后台任务运行方法_nohup与&使用技巧【技巧】  php结合redis实现高并发下的抢购、秒杀功能的实例  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  大连网站制作公司哪家好一点,大连买房网站哪个好?  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程