改变数据类的标准方法frozen
是使用dataclasses.replace
:
old_bar = Bar(foo=123)
new_bar = dataclasses.replace(old_bar, foo=456)
assert new_bar.foo == 456
对于更复杂的用例,您可以使用来自以下网址的 dataclass utils 模块:https ://github.com/google/etils
它添加了一个my_dataclass = my_dataclass.unfrozen()
成员,允许frozen
直接改变数据类
# pip install etils[edc]
from etils import edc
@edc.dataclass(allow_unfrozen=True) # Add the `unfrozen()`/`frozen` method
@dataclasses.dataclass(frozen=True)
class A:
x: Any = None
y: Any = None
old_a = A(x=A(x=A()))
# After a is unfrozen, the updates on nested attributes will be propagated
# to the top-level parent.
a = old_a.unfrozen()
a.x.x.x = 123
a.x.y = 'abc'
a = a.frozen() # `frozen()` recursively call `dataclasses.replace`
# Only the `unfrozen` object is mutated. Not the original one.
assert a == A(x=A(x=A(x = 123), y='abc'))
assert old_a == A(x=A(x=A()))
如示例中所示,您可以返回数据类的unfrozen
/frozen
副本,该数据类被明确设计为改变嵌套的数据类。
@edc.dataclass
还向数据类添加一个a.replace(**kwargs)
方法(的别名dataclasses.dataclass
)
a = A()
a = a.replace(x=123, y=456)
assert a == A(x=123, y=456)