slots 定义后实例还能有 dict 吗?内存节省多少

来源:Android社区作者:会飞的猪头衔:草根站长
导读:本期聚焦于小伙伴创作的《slots 定义后实例还能有 dict 吗?内存节省多少》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《slots 定义后实例还能有 dict 吗?内存节省多少》有用,将其分享出去将是对创作者最好的鼓励。

在Python类定义中使用slots可以限制实例的属性,同时改变实例的属性存储方式,很多开发者会疑惑定义slots之后,类的实例是否还会拥有dict属性,以及这种用法能带来多少内存节省。实际上slots对实例dict的影响和内存优化的效果,都和slots的具体定义方式、实例属性的使用情况直接相关。

slots定义后实例是否还有dict

默认情况下,Python类的实例会有一个__dict__属性,用来存储实例的动态属性,这个字典也是实例占用内存较多的重要原因之一。当我们给类定义__slots__时,实例的__dict__存在情况分为两种:

仅定义普通属性名到slots

如果__slots__中只包含字符串形式的属性名,没有包含'__dict__',那么实例默认不会拥有__dict__属性,此时实例不能动态添加slots之外的属性。

class NormalSlots:
    __slots__ = ('name', 'age')

obj = NormalSlots()
obj.name = "test"
# 下面这行会报错,因为没有__dict__,不能动态添加属性
# obj.gender = "male"
print(hasattr(obj, '__dict__'))  # 输出 False

slots中包含'__dict__'

如果__slots__的定义中显式包含了'__dict__',那么实例仍然会拥有__dict__属性,此时实例可以动态添加slots之外的属性,不过这种情况下slots的内存优化效果会打折扣。

class SlotsWithDict:
    __slots__ = ('name', 'age', '__dict__')

obj = SlotsWithDict()
obj.name = "test"
obj.gender = "male"  # 可以动态添加属性
print(hasattr(obj, '__dict__'))  # 输出 True
print(obj.__dict__)  # 输出 {'gender': 'male'}

slots能节省多少内存

slots节省内存的核心原因是,它让实例不再使用__dict__存储属性,而是使用固定大小的数组存储,减少了字典的开销。我们可以通过sys.getsizeof来测算不同情况下实例的内存占用。

测试代码示例

import sys

class NoSlots:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class WithSlots:
    __slots__ = ('name', 'age')
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 创建实例
no_slots_obj = NoSlots("张三", 20)
with_slots_obj = WithSlots("张三", 20)

# 计算实例本身的内存占用,注意getsizeof不会递归计算引用对象的大小
print(f"无slots实例内存: {sys.getsizeof(no_slots_obj)} 字节")
print(f"有slots实例内存: {sys.getsizeof(with_slots_obj)} 字节")

测试结果说明

在64位Python环境下,上述测试的输出通常类似如下:

  • 无slots实例内存: 56 字节
  • 有slots实例内存: 24 字节

可以看到单个实例就能节省32字节左右的内存,如果程序中需要创建成千上万个同类型的实例,内存节省的效果会非常明显。如果slots中包含了'__dict__',那么实例的内存占用会介于两者之间,因为既要存储固定数组,也要存储字典的部分开销。

slots使用的注意事项

虽然slots能优化内存,但也不是所有场景都适合使用:

  • slots定义的类继承时需要注意,子类如果没有定义__slots__,会自动拥有__dict__,之前的优化效果会失效。
  • slots会限制实例的动态属性添加,除非显式把'__dict__'加入slots,否则不能给实例添加未定义的属性。
  • 对于属性很少、实例数量不多的类,使用slots带来的收益不大,反而会增加代码的复杂度。
总结来说,默认情况下定义slots后实例没有dict,只有在slots中显式加入'__dict__'时实例才会有dict;slots的内存节省效果和实例数量、属性数量相关,大量实例场景下能显著降低内存占用。

slots__dict__实例内存Python内存优化__slots__修改时间:2026-06-22 06:36:57

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。