找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2410

积分

1

好友

333

主题
发表于 2025-12-25 02:05:12 | 查看: 31| 回复: 0

在Python的对象模型中,一个关键设计是:实例的属性并非作为固定字段存储在对象内部,而是统一保存在一个名为 __dict__ 的映射结构里。深入理解 __dict__,就是理解Python中实例属性从何而来、如何被查找与销毁,以及实例命名空间的生命周期与作用边界。

一、定义与本质:实例的专属命名空间

__dict__ 是一个字典对象,它存储着实例对象独有的“实例级属性”。

class A:
    pass

a = A()
a.x = 10
print(a.__dict__)    # 输出:{'x': 10}
type(a.__dict__)     # 输出:<class 'dict'>

它本质上就是实例的命名空间,其键为属性名(字符串),值为对应的属性值。每个实例都拥有自己独立的 __dict__,互不干扰:

a1 = A()
a2 = A()
a1.x = 1
a2.x = 2
print(a1.__dict__)    # 输出:{'x': 1}
print(a2.__dict__)    # 输出:{'x': 2}

二、创建机制:运行时的动态绑定

Python的实例属性无需提前声明。对实例属性的任何赋值操作,都会直接写入其 __dict__

a.y = 20

上面的操作等价于:

a.__dict__['y'] = 20

这揭示了Python运行时动态绑定的核心特性__dict__ 是实例属性创建的主要存储位置(不考虑使用了 __slots__ 的特殊情况)。

删除属性同理:

del a.y
# 等价于
del a.__dict__['y']

三、在属性查找中的优先级位置

当你访问 instance.attr 时,Python遵循一个固定的查找链(简化版):

  1. 实例 instance.__dict__
  2. Class.__dict__
  3. 父类 __dict__(按MRO顺序)
  4. 若仍未找到,触发 __getattr__()

可见,实例 __dict__ 拥有最高优先级。例如:

class A:
    x = 100  # 类属性

a = A()
a.x = 10     # 创建实例属性
print(a.x)   # 输出:10,访问的是实例属性
print(A.x)   # 输出:100,访问的是类属性

原因是 a.__dict__ == {'x': 10},实例属性遮蔽了同名的类属性。

四、生命周期:与实例共存亡

__dict__ 的生命周期与其所属实例对象完全一致。

  1. 创建时:实例化后即拥有一个空的 __dict__
    a = A()
    a.__dict__ == {}  # True
  2. 使用中:随着属性的增删改,__dict__ 的内容持续变化。
  3. 销毁时:当实例被垃圾回收,其 __dict__ 也随之销毁,不存在任何“属性残留”。

五、与方法、描述符的关系

  1. 实例方法不存于__dict__
    方法定义在类中,存储于类的 __dict__ 里,通过描述符机制绑定到实例。因此检查 'method_name' in instance.__dict__ 会返回 False

  2. 数据描述符的优先级
    对于实现了 __get____set__数据描述符(如 property),其优先级高于实例 __dict__

    class A:
        @property
        def x(self):
            return 42
    
    a = A()
    a.__dict__['x'] = 100  # 尝试直接写入实例字典
    print(a.x)             # 输出:42,描述符优先

六、与__slots__的互斥关系

当类使用 __slots__ 时,情况发生根本改变:

class A:
    __slots__ = ('x',)

a = A()
a.x = 1
hasattr(a, '__dict__')  # 输出:False (默认情况下)

__slots__ 会移除实例的 __dict__,将实例属性改为静态存储,从而改变整个命名空间模型。若需显式保留 __dict__,可将其加入 __slots__ 列表。

七、常见误解澄清

  • 误解1:实例属性存放在类中。
    正解:实例属性存储在实例自身的 __dict__ 中。
  • 误解2:实例 __dict__ 与类 __dict__ 是同一个。
    正解:它们是完全独立的命名空间。
  • 误解3:方法是实例的一部分。
    正解:方法属于类,通过描述符机制进行绑定。
  • 误解4:删除实例会影响类属性。
    正解:不会。实例 __dict__ 的生命周期与类无关。

总结

__dict__ 是Python实例的核心命名空间,它以字典形式动态存储运行期绑定的属性。其生命周期与实例同步,在属性查找链中通常享有最高优先级。对实例属性的操作,实质是对 __dict__ 的字典操作。掌握 __dict__,是深入理解Python动态对象模型、属性解析机制和内存管理的关键。

实例__dict__示意图




上一篇:Neo4j 批量创建节点实战:以刘德华与番茄为例构建知识图谱数据模拟
下一篇:沃尔玛App数字化零售观察:供应链如何重塑大众价格体系认知
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-11 20:16 , Processed in 0.241641 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表