Python中__slots__用法详解与内存优化指南
本文详细介绍 Python 中 __slots__ 的用法。通过定义该特殊属性,可以限制类的实例只能分配指定的属性名称,防止意外添加动态属性。同时,它会替代默认的字典存储机制,改用更紧凑的数据结构,从而在批量创建大量对象时显著降低内存开销并提升运行效率。
核心原理与性能优势
在 Python 中,默认情况下每个类的实例都会维护一个 __dict__ 字典来动态绑定属性。这种灵活性意味着可以随时给对象添加新属性,但也带来了额外的内存消耗和查询开销。引入 __slots__ 后,实例将不再使用字典,而是采用类似元组或数组的固定槽位来存储数据。这不仅使得属性赋值被严格限制在预定义的范围内,还能大幅压缩单对象内存空间,在处理成千上万个实例的高频业务时尤为明显。
实际操作步骤
第1步:定义带 __slots__ 的类结构
要在类中启用此功能,只需在类体内部声明一个名为 __slots__ 的属性。其值可以是字符串列表或元组,列出了该实例允许拥有的所有变量名:
class Account(object):
__slots__ = ('name', 'balance')
class Test(object):
def __init__(self, name):
self.name = name
在此结构中,Account 类的任何实例都只能分配 name 和 balance 两个属性。初始化完成后,对象底层仅开辟这两个槽位的空间。
第2步:验证属性限制与异常捕获
尝试为开启了 __slots__ 的实例赋予列表中未包含的新属性,解释器会抛出 AttributeError。这能有效拦截拼写错误导致的静默 bug,例如不小心写了错别字作为新键名:
acct = Account()
acct.name = 'Alice'
acct.balance = 1000
# acct.age = 25 # 取消注释执行此处会引发 AttributeError
第3步:对比内存占用情况
借助标准库 sys.getsizeof() 可以直观观察到两者的体积差异。普通类实例通常多出几十字节的字典开销:
import sys
class NormalClass:
def __init__(self, x, y):
self.x = x
self.y = y
class SlottedClass:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
print(sys.getsizeof(NormalClass(1, 2))) # 输出较大的数值
print(sys.getsizeof(SlottedClass(1, 2))) # 输出较小的紧凑数值
兼容性与注意事项
当子类继续继承带有 __slots__ 的父类时,必须在子类的 __slots__ 中也进行显式声明,否则子类将退化为使用 __dict__ 的动态模式。此外,由于放弃了字典映射机制,无法再通过常规的字典遍历方式来查看对象当前状态,若需保留部分灵活性,可在 __slots__ 中包含预留的通用键(如 '_extra')来手动挂载额外数据。
总结
合理使用 __slots__ 是 Python 开发中经典的性能调优手段。它不仅规范了对象的接口行为,还切实降低了系统资源负担。以上就是 Python 中 __slots__ 用法实例的详细教程,更多关于 Python 进阶技巧与性能优化的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









