【发布时间】:2020-05-10 21:28:45
【问题描述】:
请注意,我已经提到了 StackOverflow 问题 here。我发布这个问题是为了调查调用__post_init__ 是否安全。请检查问题直到最后。
检查以下代码。在第 3 步中,我们从 yaml 字符串加载 dataclass A。注意它不会调用__post_init__ 方法。
import dataclasses
import yaml
@dataclasses.dataclass
class A:
a: int = 55
def __post_init__(self):
print("__post_init__ got called", self)
print("\n>>>>>>>>>>>> 1: create dataclass object")
a = A(33)
print(a) # print dataclass
print(dataclasses.fields(a))
print("\n>>>>>>>>>>>> 2: dump to yaml")
s = yaml.dump(a)
print(s) # print yaml repr
print("\n>>>>>>>>>>>> 3: create class from str")
a_ = yaml.load(s)
print(a_) # print dataclass loaded from yaml str
print(dataclasses.fields(a_))
我现在看到的解决方案是在最后自己调用__-post_init__,就像下面的代码 sn-p 一样。
a_.__post_init__()
我不确定这是否是对yaml 序列化dataclass 的安全再现。另外,当dataclass字段为dataclasses.InitVar类型时,__post_init__取kwargs也会带来问题。
【问题讨论】:
-
如果你加载的东西没有实现 __post_init__() 怎么办?我能问你为什么使用 YAML 来保存对象而不是 pickle 吗?
-
如果我不实现 __post_init__() 一切正常,但我希望在加载数据类时做一些事情。我使用 yaml 而不是 pickle 我想在未来使用干净的 yaml 接口构建 rest API。
标签: python-3.x yaml pyyaml python-dataclasses