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

如何在冻结dataclass初始化时添加动态生成的属性

解决方案

对于冻结的dataclass,你不能直接在__post_init__中赋值属性,也不能用name.lower()作为默认值(类定义阶段name并非实例属性,会引发NameError),以下是两种可行的实现方式:

方法1:利用object.__setattr__在__post_init__中赋值

冻结dataclass重写了__setattr__方法阻止修改,但可以直接调用父类object.__setattr__来绕过限制,实现和第一个类一致的结构:

from dataclasses import dataclass, field
from typing import Optional

@dataclass(frozen=True)
class SecondClass:
    name: str
    code: Optional[str] = field(init=False)

    def __post_init__(self):
        # 绕过冻结类的赋值限制,初始化code属性
        object.__setattr__(self, 'code', self.name.lower())

这种方式会在实例初始化时就生成code属性,作为实例的固定字段存在,和FirstClass的行为保持一致。

方法2:使用cached_property生成缓存属性

如果你的核心需求是缓存计算结果,可以用Python 3.8+提供的functools.cached_property,它会自动缓存第一次计算的结果,后续访问直接读取缓存,无需额外定义字段:

from dataclasses import dataclass
from functools import cached_property

@dataclass(frozen=True)
class SecondClass:
    name: str

    @cached_property
    def code(self) -> str:
        return self.name.lower()

这种方式更轻量,code会在第一次访问时生成并缓存,适合数据量大、读取成本高的场景,同时完全符合冻结类的只读特性。


内容的提问来源于stack exchange,提问作者brightstar2100

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:45:42