首先,让我介绍一个可行的简单示例。
import yaml
class Child:
def __init__(self):
self.nc1 = 11
self.nc2 = 22
class WorkingParent:
def __init__(self):
self.p1 = 11
self.p2 = 22
self.nc = Child()
parent = WorkingParent()
yaml_parent_str = yaml.dump(parent)
print("**** yaml_parent_str ***")
print(yaml_parent_str)
print("**** parent_from_yaml_str ***")
parent_from_yaml_str = yaml.load(yaml_parent_str)
print(parent_from_yaml_str)
此控制台输出如下所示,这是正确的。 YAML能够从str yaml_parent_str
**** yaml_parent_str ***
!!python/object:__main__.WorkingParent
nc: !!python/object:__main__.Child {nc1: 11, nc2: 22}
p1: 11
p2: 22
**** parent_from_yaml_str ***
<__main__.WorkingParent object at 0x000001A5BF200470>
现在让我们看看什么不起作用
import yaml
class NotWorkingParent:
class NestedChild:
def __init__(self):
self.nc1 = 11
self.nc2 = 22
def __init__(self):
self.p1 = 11
self.p2 = 22
self.nc = NotWorkingParent.NestedChild()
parent = NotWorkingParent()
yaml_parent_str = yaml.dump(parent)
print("**** yaml_parent_str ***")
print(yaml_parent_str)
print("**** parent_from_yaml_str ***")
parent_from_yaml_str = yaml.load(yaml_parent_str)
print(parent_from_yaml_str)
结果如下。您会看到YAML无法通过str yaml_parent_str
创建对象。
**** yaml_parent_str ***
!!python/object:__main__.NotWorkingParent
nc: !!python/object:__main__.NestedChild {nc1: 11, nc2: 22}
p1: 11
p2: 22
**** parent_from_yaml_str ***
yaml.constructor.ConstructorError: while constructing a Python object
cannot find 'NestedChild' in the module '__main__'
in "<unicode string>", line 2, column 5:
nc: !!python/object:__main__.NestedC ...
^
您可以看到问题出在YAML lib认为NestedClass
是
nc: !!python/object:__main__.NestedChild {nc1: 11, nc2: 22}
代替
nc: !!python/object:__main__.NotWorkingParent.NestedChild {nc1: 11, nc2: 22}
这怎么解决???
答案 0 :(得分:0)
告诉PyYAML应该用于类的标记
import yaml
class Parent(yaml.YAMLObject):
yaml_tag = u'!Parent'
yaml_loader = yaml.SafeLoader
class NestedChild(yaml.YAMLObject):
yaml_tag = u'!Child'
yaml_loader = yaml.SafeLoader
def __init__(self):
self.nc1 = 11
self.nc2 = 22
def __init__(self):
self.p1 = 11
self.p2 = 22
self.nc = Parent.NestedChild()
parent = Parent()
yaml_parent_str = yaml.dump(parent)
print("**** yaml_parent_str ***")
print(yaml_parent_str)
print("**** parent_from_yaml_str ***")
parent_from_yaml_str = yaml.safe_load(yaml_parent_str)
print(parent_from_yaml_str)
通过衍生自yaml.YAMLObject
,您可以使用yaml_tag
指定标签。请注意,我还设置了yaml_loader
,以便可以使用yaml.safe_load
代替yaml.load
,这应该总是这样做,因为yaml.load
是一个安全问题,因为用户可能会导致代码实例化任意类。