LEEFEI571 发表于 2025-4-11 21:53:12

__slots__类属性的问题

小甲鱼老师在讲解__slots__类属性时,课后作业有以下这道题:

>>> class C:
...   __slots__ = ['x']
...      
>>> c = C()
>>> c.x = 520
>>> c.__dict__
# 请问这里会打印什么内容?

答案是会报错,因为使用了 __slots__ 属性,那么对象就会划分一个固定大小的空间来存放指定的属性,这时候 __dict__ 属性就不需要了,空间也就节约了出来。

我的困惑是对象c的x属性保存到了哪里?麻烦大神帮忙指点,谢谢!

FishC 发表于 2025-4-11 21:55:51

关于 __slots__ 属性存储的解答

当类使用 __slots__ 时,实例属性会存储在一个固定大小的数组中,而不是传统的 __dict__ 字典里。以下是具体分析:


[*]问题复现分析:
你的示例代码中 __slots__ = 语法不完整(缺少赋值内容),实际应为类似 __slots__ = ()。此时:

class C:
    __slots__ = ()# 明确设置为空元组

c = C()
c.x = 520          # 这里会直接报错!

因为 __slots__ = () 表示禁止实例添加任何属性,执行 c.x = 520 会抛出 AttributeError。

[*]属性存储逻辑:
如果 __slots__ 包含属性名(例如 __slots__ = ("x",)),则实例的 x 会存储在 预分配的内存槽位中,而不是 __dict__。此时:

class C:
    __slots__ = ("x",)# 明确允许属性 x

c = C()
c.x = 520            # 正常存储到槽位
c.__dict__             # 报错!因未生成 __dict__


[*]你的困惑点:
你的示例中可能漏写了 __slots__ 的具体值,导致代码实际允许动态添加属性。但若严格按 __slots__ = () 执行,c.x = 520 会直接报错,不会走到 c.__dict__ 这一步。


总结:

[*]若 __slots__ 包含属性名 → 属性存储在固定槽位,无 __dict__
[*]若 __slots__ 为空 → 实例无法添加任何属性(除非继承父类属性)
[*]若未定义 __slots__ → 属性存储在 __dict__ 字典


建议检查代码中 __slots__ 的赋值是否完整,确保与实际需求一致!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

player-none 发表于 2025-4-22 17:34:31

那么对象就会划分一个固定大小的空间来存放指定的属性

这个空间里

求最佳
页: [1]
查看完整版本: __slots__类属性的问题