You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为带有slots=True的dataclass定义__dict__属性?

如何为带有slots=True的dataclass定义__dict__属性?

这个问题我之前也碰到过,咱们先理清楚为啥你原来的代码会报错,再给出可行的解决方案~

首先看你提供的示例代码:

from dataclasses import dataclass

@dataclass(slots=True)
class Circle:
    radius:int = 2

    @property
    def myslots(self):
        return self.__slots__

    @property
    def __dict__(self):
        return self.__slots__

c = Circle()
print(c.myslots)
print(c.__dict__)

运行后会抛出AttributeError: 'Circle' object has no attribute '__dict__',原因很简单:当给dataclass设置slots=True且没有显式把__dict__加入slots列表时,Python不会为实例创建__dict__属性。而__dict__是Python的特殊属性,访问它时会优先查找实例本身的属性,找不到就直接报错,不会去调用我们定义的@property。

接下来给你两种解决方案:

方案一:换个属性名(推荐,保留slots的内存优势)

既然__dict__容易和内置逻辑冲突,我们可以换个更清晰的名字,比如to_dict,手动遍历slot中的属性,把它们转换成字典:

from dataclasses import dataclass

@dataclass(slots=True)
class Circle:
    radius:int = 2

    @property
    def myslots(self):
        return self.__slots__

    @property
    def to_dict(self):
        # 遍历所有slot属性,生成对应的键值对字典
        return {slot: getattr(self, slot) for slot in self.__slots__}

c = Circle()
print(c.myslots)  # 输出 ('radius',)
print(c.to_dict)  # 输出 {'radius': 2}

方案二:显式将__dict__加入slots(适合必须用__dict__的场景)

如果你因为某些需求一定要用__dict__这个名字,可以在slots列表里显式添加它,这样Python会为实例创建__dict__属性,之后我们就能用@property覆盖它的行为了:

from dataclasses import dataclass

@dataclass(slots=True)
class Circle:
    radius:int = 2
    # 显式把__dict__加入slots
    __slots__ = ('radius', '__dict__')

    @property
    def myslots(self):
        return self.__slots__

    @property
    def __dict__(self):
        # 自定义返回内容,排除__dict__本身
        return {slot: getattr(self, slot) for slot in self.__slots__ if slot != '__dict__'}

c = Circle()
print(c.myslots)  # 输出 ('radius', '__dict__')
print(c.__dict__)  # 输出 {'radius': 2}

不过要注意,这种方式会让实例拥有真正的__dict__,会损失slots原本节省内存的优势,所以除非有特殊需求,更推荐第一种方案。

备注:内容来源于stack exchange,提问作者robertspierre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:04:30