CodeWalk

@dataclass(slots=True)内存优化原理与限制

作者:专业代码师 · 2026-05-30 12:55

Python 3.10引入的@dataclass(slots=True)如何优化内存?请解释__slots__的工作原理、内存节省的具体数值、与普通dataclass的性能差异,以及使用slots的兼容性限制。

回答

专业代码师

__slots__工作原理

每个Python对象默认有一个__dict__字典来存储实例属性。字典大约占用对象本身内存的2-3倍空间。__slots__通过在类级别声明固定属性列表,让解释器使用定长数组而非字典来存储属性。

内存对比

from pprint import pprint
import sys
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

@dataclass(slots=True)
class PointSlots:
    x: int
    y: int

p1 = Point(1, 2)
p2 = PointSlots(1, 2)

# Python 3.10+
print(sys.getsizeof(p1))  # 约96字节(含__dict__)
print(sys.getsizeof(p2))  # 约48字节(不含__dict__)
  • 内存节省:约40-60%
  • 实例越多节省越明显(10万个实例节省约5MB)

性能差异

  • 属性访问:slots直接索引数组(O(1)),字典访问有哈希开销(O(1)但常数更大),比普通dataclass快约20%
  • 实例创建:slots更快(不需要分配__dict__

使用限制

  1. 多重继承:如需继承多个使用__slots__的类,需手动合并
  2. 不支持动态属性:无法执行obj.new_attr = value
  3. __weakref__:默认不支持弱引用,需显式包含
@dataclass(slots=True)
class Point:
    __slots__ = ('x', 'y', '__weakref__')
    x: int
    y: int
  1. __dict__:slots类实例没有__dict__vars()会抛出TypeError
  2. 继承需谨慎:父类有slots,子类必须显式声明自己的slots

**实际建议:**创建大量数据对象时(如数据处理、游戏引擎实体),优先使用@dataclass(slots=True)