定义以下子类:
from dataclasses import dataclass, replace, field, InitVar
@dataclass
class MyDataClass:
foo: InitVar[str]
bar: str
foo_len: int = field(init=False)
def __post_init__(self, foo: int):
self.foo_len = len(foo)
并创建其实例:
instance = MyDataClass(foo="foo", bar="bar")
尝试在实例上调用replace
失败:
In[5]: replace(instance, bar="baz")
Traceback (most recent call last):
File "/home/or/.venv/m/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 3343, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-5-5de186c91dc9>", line 1, in <module>
replace(instance, bar="baz")
File "/home/or/.venv/m/lib/python3.6/site-packages/dataclasses.py", line 1170, in replace
changes[f.name] = getattr(obj, f.name)
AttributeError: 'MyDataClass' object has no attribute 'foo'
据我所知,InitVar
应该只在init期间存在,但是从一些调查中,我可以看到它们被放入了__dataclass_fields__
,因此replace
正在尝试使用它们
我使用的是Python3.6,所以我的dataclasses
包是后端口,而不是Python3.7+的内置包
我在dataclasses的文档中发现了这一行:
Init-only variables without default values, if any exist, must be specified on the call to replace() so that they can be passed to init() and post_init().
这意味着如果我有instance.foo
的原始值,理论上我可以:
replace(instance, bar="baz", foo="value of foo")
但是我没有instance.foo
的原始值
如果要创建dataclass现有实例的副本,如何避免此错误
数据类中有
InitVar
意味着如果不再次显式地传递InitVar
,就不能调用构造函数。如果您不再有权访问InitVar
,则这将取消replace(instance, ...)
和MyDataClass(**asdict(instance), ...)
的使用资格如果您所关心的只是获取一个有效的副本,那么您可以使用标准库的
copy.copy
(或者copy.deepcopy
用于有自己容器的数据类,或者嵌套的数据类),它不调用实例的构造函数:相关问题 更多 >
编程相关推荐