变异的标准方法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 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)