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

如何在冻结的dataclass中初始化列表字段的副本?

解决冻结Dataclass中列表字段创建副本的问题

针对你遇到的冻结dataclass无法在__post_init__中修改字段,同时需要为other列表创建副本的问题,有两种简洁的解决方式:

方法一:使用field的converter参数(Python 3.10+)

从Python 3.10开始,dataclasses.field支持converter参数,可以在字段初始化时自动转换传入的值。直接给other字段添加转换器,生成列表副本:

from dataclasses import dataclass, field
from typing import List

@dataclass(frozen=True, eq=True)
class Node:
    name: str
    rate: int
    other: List[str] = field(compare=False, converter=lambda lst: lst.copy())

这样每次传入other参数时,转换器会自动创建列表副本,既不用重写__init__,也不会触发冻结实例的赋值限制。

方法二:重写__init__并使用object.__setattr__(兼容低版本Python)

如果你的Python版本低于3.10,没有converter参数,可以重写__init__,借助object.__setattr__绕过冻结实例的赋值限制,手动创建列表副本:

from dataclasses import dataclass, field
from typing import List

@dataclass(frozen=True, eq=True)
class Node:
    name: str
    rate: int
    other: List[str] = field(compare=False)

    def __init__(self, name: str, rate: int, other: List[str]):
        # 先创建传入列表的副本
        other_copy = other.copy()
        # 用object.__setattr__给冻结实例赋值,避免触发不可变限制
        object.__setattr__(self, 'name', name)
        object.__setattr__(self, 'rate', rate)
        object.__setattr__(self, 'other', other_copy)

这种方式只需要简单重写__init__,不用手动处理所有dataclass的初始化逻辑,符合dataclass的使用初衷。

两种方法都能保证other字段是独立的副本,修改它不会影响原始解析结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:40:34