Python 当其中一个对象是嵌套类时,PyYaml无法从字符串加载YAML

Python 当其中一个对象是嵌套类时,PyYaml无法从字符串加载YAML,python,yaml,Python,Yaml,首先,让我介绍一个简单的例子 进口yaml 班级儿童: 定义初始自我: self.nc1=11 self.nc2=22 类WorkingParent: 定义初始自我: self.p1=11 self.p2=22 self.nc=Child 父项=工作父项 yaml\u parent\u str=yaml.dumpparent 打印****yaml_parent_str*** printymal_parent_str 打印****来自yaml街的父项*** 父项\u from\u yaml\u s

首先,让我介绍一个简单的例子

进口yaml 班级儿童: 定义初始自我: self.nc1=11 self.nc2=22 类WorkingParent: 定义初始自我: self.p1=11 self.p2=22 self.nc=Child 父项=工作父项 yaml\u parent\u str=yaml.dumpparent 打印****yaml_parent_str*** printymal_parent_str 打印****来自yaml街的父项*** 父项\u from\u yaml\u str=yaml.loadyaml\u父项\u str 打印来自_yaml_街的父_ 此控制台输出如下所示,这是正确的。YAML能够从str YAML_parent_str创建对象

结果如下。您可以看到YAML无法从str YAML_parent_str创建对象

而不是

nc: !!python/object:__main__.NotWorkingParent.NestedChild {nc1: 11, nc2: 22}

如何解决这个问题?

告诉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_标记指定标记。请注意,我还设置了yaml_loader,这样您就可以使用yaml.safe_load而不是yaml.load,这应该始终做到,因为yaml.load是一个安全问题,因为用户可能会导致代码实例化任意类。

感谢您的响应,但我不想将yaml.YAMLObject子类化。。。您可以建议如何实现这一点吗?您也可以使用带有自定义标记的yaml.add_representer和yaml.add_构造函数,但是您需要自己实现加载和转储对象。我建议改为将yaml.YAMLObject子类我不想那样做“这不是一个很好的解决方案。嗯,我也试过了,但我不能支持YAML序列化的子类…我需要让每个子类都兼容…相反,我重写了getstate以支持子类…所以基本上我不喜欢YAML.add_构造函数和YAML.add_representer,但相反,我认为我需要在主模块中创建一个伪引用,如NestedChild=Parent.NestedChild
nc: !!python/object:__main__.NestedChild {nc1: 11, nc2: 22}
nc: !!python/object:__main__.NotWorkingParent.NestedChild {nc1: 11, nc2: 22}
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)