__slots__用于限制实例属性、节省内存并加速访问;它禁用__dict__,仅允许预定义属性,子类需显式继承,且需注意弱引用和多重继承冲突。

在 Python 中,__slots__ 是一种用于限制实例可动态添加属性的机制,它能减少内存占用、提升属性访问速度,并明确类的属性边界。
为什么用 __slots__?
默认情况下,Python 实例通过 __dict__ 存储所有属性,这带来灵活性但也带来开销。启用 __slots__ 后,实例不再拥有 __dict__(除非显式保留),只允许定义在 __slots__ 中的属性被设置,从而:
- 节省内存:避免为每个实例创建字典对象
- 加快属性读写:跳过字典查找,直接定位到固定偏移量
- 防止误赋值:对未声明的属性赋值会触发
AttributeError
基本用法与语法
在类定义中,将 __slots__ 声明为一个字符串元组或列表,列出允许的属性名:
class Person:
__slots__ = ('name', 'age')
<p>p = Person()
p.name = 'Alice' # ✅ 允许
p.age = 30 # ✅ 允许
p.city = 'Beijing' # ❌ AttributeError: 'Person' object has no attribute 'city'
注意:__slots__ 只约束**实例属性**,不影响类属性或方法;也不影响通过 __setattr__ 等自定义方式绕过(但需谨慎)。
立即学习“Python免费学习笔记(深入)”;
本文档主要讲述的是Subversion安装使用说明文档;Subversion是一个自由/开源的版本控制系统,正逐步替代CVS。Subversion的版本库可以通过网络访问,从而使用户可以在不同的电脑上进行操作。 Subversion可支持版本化的目录、真实的版本历史、原子提交、版本化的无数据、可选的网络层、一致的数据操作、高效的分支和标签操作和可修改性。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
继承与 __slots__ 的配合
子类默认不继承父类的 __slots__。若子类也定义了 __slots__,则最终允许的属性是两者并集(但需手动合并);若子类未定义,则会恢复使用 __dict__,失去限制效果。
常见安全写法:
- 父子类都定义
__slots__,并在子类中显式包含父类的 slot 项 - 若希望子类也受限制,避免遗漏,可这样写:
__slots__ = ('new_attr',) + Parent.__slots__ - 若子类需要动态属性,可显式加入
'__dict__'到__slots__中(但会削弱内存优势)
注意事项和常见陷阱
__slots__ 虽好,但有几处容易出错:
- 不能与
__dict__共存(除非显式加入'__dict__') - 不能用于有
__weakref__需求却未声明'__weakref__'的类(否则无法创建弱引用) - 多重继承时,若多个父类都有
__slots__,且内容冲突(如重复 slot 名),会报错 - 使用
dataclass或NamedTuple时,它们内部可能已处理__slots__,需查阅文档确认行为
不复杂但容易忽略。









