位置:首页 > Python > Python中为什么__slots__能显著降低大规模实例对象内存占用

Python中为什么__slots__能显著降低大规模实例对象内存占用

时间:2026-08-14  |  作者:深海捕梦者  |  阅读:0

__slots__能省几十到上百字节,因为禁用__dict__字典(约240字节开销)而改用紧凑数组存储属性,每个字段仅占8字节指针并采用偏移寻址。

为什么Python中的Slots属性可以显著降低大规模实例对象的内存?

__slots__ 为什么能省下几十到上百字节?

Python 默认会给每个实例分配一个 __dict__ 字典。哪怕只存一个 int,在 64 位 CPython 里,这个字典也要占掉约 240 字节。

它之所以这么大,是因为背后还带有哈希表头、空桶数组、引用计数这些“基础税”。

__slots__ 的核心做法,就是直接禁用 __dict__ 它改用更紧凑的数组来保存属性值。

这样一来,每个字段通常只占一个指针大小,也就是 8 字节左右。访问时走的是偏移寻址,连哈希计算这一步都省掉了。

什么时候省内存效果最明显?

不是所有类都值得加 __slots__,关键还是看使用场景。

  • 对象数量 ≥ 1 万,且结构固定(如坐标 Point、特征向量 FeatureRow、事件消息 IoTEvent
  • 每个实例只存 2–5 个字段,但 __dict__ 开销占比奇高(实测 10 万个 Point 实例:普通类约 24 MB,加 __slots__ 后约 14 MB)
  • 部署在内存受限环境(边缘设备、Serverless 函数、容器化微服务)
  • 不用 __dict__ 动态赋值、不依赖第三方库的运行时属性注入(如 Django ORM、某些序列化工具)

对象越多、字段越固定,__slots__ 的省内存优势通常越明显。

常见踩坑点:为什么加了 __slots__ 还没省内存?

很多时候,问题不在语法本身,而在一些隐性条件没有满足。

  • 子类没声明自己的 __slots__ → 父类的 __slots__ 白写,__dict__ 照常生成
  • 继承链里任一父类带 __dict__(比如继承了 Exception 或某些第三方基类)→ 整个继承链退化
  • __slots__ = 'x' 写成单字符串 → 被当成 ('x',) 的误写,实际拆成 ('x',) 是对的,但 __slots__ = 'xy' 会被拆成 ('x', 'y'),极易出错
  • 漏写私有字段(如 _cache__internal)→ 运行时报 AttributeError,但不会报内存问题,容易被忽略

@dataclass(slots=True) 和手写 __slots__ 有什么区别?

Python 3.10+ 的 @dataclass(slots=True) 等价于手写 __slots__,但使用时仍要注意几个点。

  • 它自动生成 __init____repr__,省事;但若父类没 __slots__slots=True 无效
  • 不能像手写那样灵活控制(比如显式加入 '__weakref__' 支持弱引用)
  • 调试时看不到 __dict__vars(obj) 报错,得用 obj.__slots__ 配合 getattr 查字段

结论

真正难的不是加一行 __slots__,而是确认整个继承链干净、所有可能赋值的字段名都列全、且上下游工具链不依赖 __dict__

漏掉任意一环,内存账就算不准。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多