__slots__ 的核心作用是限制实例可动态添加的属性并显著减少内存占用——通过禁用默认 __dict__,改用固定结构存储属性;它适用于数据容器、高频创建对象等场景,但需注意继承、调试和可维护性问题。

__slots__ 的核心作用是限制实例可动态添加的属性,并显著减少内存占用——它通过禁用默认的 __dict__ 字典,改用固定大小的结构存储属性值。
为什么能节省内存?
普通 Python 实例默认携带一个 __dict__(字典),用于动态存取任意属性。字典本身开销大:哈希表结构、预留空槽、键值对存储等。而 __slots__ 告诉解释器:“这个类只会有这几个属性”,于是 Python 直接在对象头后分配连续的固定字段(类似 C struct),跳过字典创建。
- 单个实例节省几十到上百字节,大量小对象(如坐标点、配置项、ORM 模型实例)累积效果极明显
- 无
__dict__意味着不能运行时新增属性(如obj.new_attr = 1会报AttributeError) - 也不再有
__weakref__,除非显式加入'__weakref__'到__slots__
怎么正确使用 __slots__?
在类定义中直接声明 __slots__ 为字符串元组或列表:
95Shop可以免费下载使用,是一款仿醉品商城网店系统,内置SEO优化,具有模块丰富、管理简洁直观,操作易用等特点,系统功能完整,运行速度较快,采用ASP.NET(C#)技术开发,配合SQL Serve2000数据库存储数据,运行环境为微软ASP.NET 2.0。95Shop官方网站定期开发新功能和维护升级。可以放心使用! 安装运行方法 1、下载软件压缩包; 2、将下载的软件压缩包解压缩,得到we
class Point:
__slots__ = ('x', 'y')
<p>p = Point()
p.x = 10
p.y = 20</p><h1>p.z = 30 # ❌ AttributeError- 子类不会自动继承父类的
__slots__;若子类也定义了__slots__,则仅生效子类声明的字段 - 若需允许动态属性,可显式包含
'__dict__'(但会失去大部分内存优势) - 避免与
@property、描述符混用时误以为它们也受 slots 约束——它们仍正常工作,只是不能被覆盖为实例属性
哪些场景特别适合?
不是所有类都该加 __slots__,适合以下情况:
立即学习“Python免费学习笔记(深入)”;
- 数据容器类:如
NamedTuple替代品、DTO、树节点、向量/矩阵元素 - 高频创建销毁的对象:网络包解析、日志事件、游戏实体
- 明确知道属性集且几乎不扩展的类(如配置类、枚举载体)
- 配合
__weakref__实现轻量缓存或观察者引用时(需手动加入 slots)
注意事项和常见误区
__slots__ 是优化手段,不是语法强制规范。用错反而影响可维护性:
- 带继承的类要小心:父类用了
__slots__,子类没用 → 子类实例仍有__dict__,但父类字段受 slots 约束,容易混乱 - 不能给类本身赋值(
Point.x = 1允许,但这是类属性,和 slots 无关) - 调试时无法用
vars(obj)查看属性(因无__dict__),可用obj.__slots__配合getattr手动遍历 - 使用
dataclass时,可通过@dataclass(slots=True)(Python 3.10+)一键启用,更简洁









