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

重新初始化dataclass对象时嵌套dataclass未重置的问题

嵌套Dataclass初始化时保留旧值的问题解决

问题重现

你定义了如下嵌套的dataclass:

from dataclasses import dataclass, field
from typing import Dict

@dataclass
class MyNestedClass():
    field1: str = ""
    field2: int = 0
    field3: Dict[str, float] = field(default_factory=dict)

@dataclass
class MyClass():
    field1: str = ""
    field2: int = 0
    field3: Dict[str, float] = field(default_factory=dict)
    field4: MyNestedClass = MyNestedClass()

执行测试代码时发现,每次重新初始化MyClass,field4会保留之前修改的内容:

my_obj = MyClass()
print(my_obj)

my_obj.field2 = 1
my_obj.field3 = {'something': 2.5}
my_obj.field4.field1 = "B"
my_obj.field4.field2 = 2
my_obj.field4.field3 = {'something else': 3.14}
print(my_obj)

my_obj = MyClass()
print(my_obj)

输出结果:

MyClass(field1='', field2=0, field3={}, field4=MyNestedClass(field1='', field2=0, field3={}))
MyClass(field1='', field2=1, field3={'something': 2.5}, field4=MyNestedClass(field1='B', field2=2, field3={'something else': 3.14}))
MyClass(field1='', field2=0, field3={}, field4=MyNestedClass(field1='B', field2=2, field3={'something else': 3.14}))

原因分析

这是Python默认参数绑定机制导致的:

  • 当你在MyClass中定义field4: MyNestedClass = MyNestedClass()时,MyNestedClass()会在定义MyClass的时刻执行,只会创建一个实例。
  • 所有后续初始化的MyClass对象都会共享这个唯一的MyNestedClass实例,修改它的属性后,新创建的MyClass对象自然会复用这个已经被修改的实例。
  • 你对field3使用field(default_factory=dict)是正确的,因为default_factory会在每次初始化MyClass对象时调用传入的函数,生成新的字典实例,避免了共享问题。

正确的初始化方式

把field4的默认值改为使用field(default_factory=MyNestedClass),这样每次初始化MyClass时都会创建新的MyNestedClass实例:

from dataclasses import dataclass, field
from typing import Dict

@dataclass
class MyNestedClass():
    field1: str = ""
    field2: int = 0
    field3: Dict[str, float] = field(default_factory=dict)

@dataclass
class MyClass():
    field1: str = ""
    field2: int = 0
    field3: Dict[str, float] = field(default_factory=dict)
    field4: MyNestedClass = field(default_factory=MyNestedClass)

再次运行测试代码,输出会恢复预期:

MyClass(field1='', field2=0, field3={}, field4=MyNestedClass(field1='', field2=0, field3={}))
MyClass(field1='', field2=1, field3={'something': 2.5}, field4=MyNestedClass(field1='B', field2=2, field3={'something else': 3.14}))
MyClass(field1='', field2=0, field3={}, field4=MyNestedClass(field1='', field2=0, field3={}))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:25:31