Python 对象模型与属性访问机制

张开发
2026/4/14 1:19:19 15 分钟阅读

分享文章

Python 对象模型与属性访问机制
1. 引言Python 的灵活性不仅体现在语法层面更来源于其高度动态的对象模型与统一的属性访问机制。相比于仅停留在“如何使用类与对象”深入理解其底层运行原理对于掌握 Django、ORM 乃至框架设计具有重要意义。本文将围绕两个核心问题展开Python 对象是如何创建的Python 属性是如何被访问和控制的2. Python 对象模型类的本质在 Python 中类并不是一种特殊结构而是一个普通对象其创建由内置元类type完成。classA:x10等价于Atype(A,(),{x:10})由此可以得到类是type的实例type本身也是type的实例自举结构type(A)istypetype(type)istype这一机制使 Python 具备极强的动态构造能力。对象创建流程对象的创建本质上是对“类对象”的一次调用aA()在 Python 内部该过程并非简单实例化而是经历如下调用链A() ↓ type.__call__(A) ↓ 1️⃣ 调用 A.__new__() → 创建实例对象 ↓ 2️⃣ 调用 A.__init__() → 初始化实例 ↓ 返回实例需要注意类之所以可以被调用是因为其元类type实现了__call____new__负责创建对象__init__负责初始化对象在一般开发中无需直接操作__call__但该机制在元类与框架设计中具有重要作用。属性存储机制Python 使用字典结构管理对象属性实例属性obj.__dict__类属性class.__dict__示例classA:x10aA()此时a.__dict__# {}A.__dict__# 包含 x: 10当执行a.x20本质为a.__dict__[x]20属性查找规则访问属性a.x默认查找顺序为1️⃣ 实例字典 obj.__dict__ 2️⃣ 类字典 class.__dict__ 3️⃣ 父类链MRO示例classA:x10aA()a.x20优先返回实例属性 20。若执行dela.x则回退至类属性返回 10。3. 属性访问机制统一入口getattribute在 Python 中所有属性访问都会统一转化为a.x → a.__getattribute__(x)因此可以认为__getattribute__是属性访问的总入口示例classA:def__getattribute__(self,name):print(访问,name)returnsuper().__getattribute__(name)兜底机制getattr当属性在正常查找流程中未找到时Python 会触发__getattr__(self,name)示例classA:def__getattr__(self,name):return999aA()a.x# 返回 999属性访问完整流程属性访问的完整流程如下a.x ↓ 1️⃣ 调用 __getattribute__(x)必定执行 ↓ 2️⃣ 若查找成功 → 直接返回 ↓ 3️⃣ 若抛出 AttributeError ↓ 4️⃣ 调用 __getattr__(x)关键区别如下方法执行时机作用__getattribute__必定执行控制所有属性访问__getattr__查找失败后提供兜底逻辑异常驱动机制需要特别强调__getattr__的触发依赖于AttributeError例如def__getattribute__(self,name):return100此时不会触发__getattr__因为属性访问并未失败。方法访问的本质在 Python 中方法本质上也是属性self.__getattr__等价于self.__getattribute__(__getattr__)因此在调试或日志中可能会看到访问 __getattr__递归风险与正确写法在重写__getattribute__时如果直接访问属性容易导致无限递归错误示例def__getattribute__(self,name):returnself.x其执行过程为self.x → __getattribute__(x) → self.x → ...最终触发RecursionError。正确写法应为returnsuper().__getattribute__(name)调试环境的特殊行为在调试工具如 PyCharm Debug中可能出现如下输出访问 __class__ 访问 __class__ ...原因在于调试器会主动访问对象属性以获取类型与结构信息例如obj.__class__这些访问同样会触发__getattribute__。需要明确这些行为来源于调试工具而非程序本身逻辑。4. 整体模型总结对象关系结构type → 类 → 实例type负责创建类类负责创建实例属性访问模型a.x ↓ __getattribute__ ↓ 内部查找 obj.__dict__ class.__dict__ 父类链 ↓ 查找失败 → __getattr__5. 工程意义上述机制在实际工程中具有直接应用价值机制应用场景__getattribute__日志系统、权限控制__getattr__安全访问、默认值处理属性查找链ORM 字段解析type/ 元类模型定义、自动注册例如Django ORM 的字段访问机制DRF 的序列化流程权限控制与中间件设计这些框架能力本质上均建立在 Python 对象模型之上。6. 总结Python 的核心机制可以归纳为两部分对象如何被创建type / __new__ / __init__ 属性如何被访问__getattribute__ / __getattr__进一步抽象为Python 对象模型 属性访问控制机制理解这一点意味着从“使用 Python”迈向“理解 Python”也是深入框架源码与系统设计的关键一步。

更多文章