__slots__ 是类的类变量,声明实例允许拥有的固定属性集合。声明后实例不再创建 __dict__ 字典,属性存进类级别的描述符对应的固定槽位,带来两个直接收益:省内存(每个实例省下一个 dict 的开销,海量小对象时效果显著)和略快的属性访问,同时顺便禁止了随意添加未声明属性。
class Point:
__slots__ = ("x", "y")
p = Point()
p.x, p.y = 1, 2
p.z = 3 # AttributeError: 没有 __dict__,不能动态加属性
易错点:
- 子类若不声明
__slots__会重新拥有__dict__,优化失效;继承链每一层都要声明。 __slots__的字符串成员会被当成单个属性名迭代(__slots__ = "xy"是坑,会用 "x"、"y" 两个名字),应写元组。- 多继承时若多个基类都有非空
__slots__会报冲突错误。 - 需要弱引用支持要加
"__weakref__"。
适用场景:实例数量巨大的数据类(如解析出的百万级记录)。注意它与命名元组/dataclass 的定位差异——日常代码优先 dataclass(3.11+ 的 dataclass 也支持 slots=True)。追问方向:没有 __dict__ 对 pickle/copy 的影响、与 __getattr__ 动态属性的冲突。