Yoh*_*hei 6 python python-dataclasses
我想知道一种使数据类bar冻结的简单方法。
@dataclass
class Bar:
foo: int
bar = Bar(foo=1)
Run Code Online (Sandbox Code Playgroud)
换句话说,我想要一个如下所示的函数some_fn_to_freeze
frozen_bar = some_fn_to_freeze(bar)
frozen_bar.foo = 2 # Error
Run Code Online (Sandbox Code Playgroud)
并且,反函数some_fn_to_unfreeze
bar = som_fn_to_unfrozen(frozen_bar)
bar.foo = 3 # not Error
Run Code Online (Sandbox Code Playgroud)
改变数据类的标准方法frozen是使用dataclasses.replace:
old_bar = Bar(foo=123)
new_bar = dataclasses.replace(old_bar, foo=456)
assert new_bar.foo == 456
Run Code Online (Sandbox Code Playgroud)
对于更复杂的用例,您可以使用以下位置的 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()))
Run Code Online (Sandbox Code Playgroud)
如示例中所示,您可以返回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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7569 次 |
| 最近记录: |