Python 如何在加载yaml时使用自定义字典类?

Python 如何在加载yaml时使用自定义字典类?,python,pyyaml,Python,Pyyaml,我目前正在加载一个类似这样的YAML文件 import yaml yaml.load('''level0: stuff: string0 level1: stuff: string1 level2: ...''') 上面的代码创建嵌套字典。 我想创建FancyDict对象的嵌套实例,而不是创建嵌套字典 class FancyDict(co

我目前正在加载一个类似这样的YAML文件

 import yaml
 yaml.load('''level0:
                 stuff: string0
                 level1: 
                     stuff: string1
                     level2: ...''')
上面的代码创建嵌套字典。 我想创建
FancyDict
对象的嵌套实例,而不是创建嵌套字典

class FancyDict(collections.MutableMapping):
   def __init__(self, *args, **kwargs):
       for name in kwargs:
          setattr(self, name, kwargs[name])
关于 似乎没有解决我想要全局重写类的情况 构造所有字典,而不是特殊标记的字典

我只需要创建/完成一个称为对象(节点?)的钩子。

有没有一种简单的方法可以做到这一点,或者我应该遍历
yaml.load
返回给我的嵌套字典并自己修复它们?

如果钩子不在那里,则构造的类型是在
construct.BaseConstructor.construct\u mapping()
中硬编码的

解决此问题的方法是创建自己的构造函数,并基于该构造函数创建自己的加载程序,然后将该加载程序作为
load()
的选项提交:

运行此命令时,您将得到一个错误,即FancyDict是一个无法实例化的抽象类:

TypeError:无法使用抽象方法实例化抽象类FancyDict
\uuuu delitem\uuuu
\uuu getitem\uuuuuuu
\uuuuu iter\uuuuuuuu
\uuuuu setitem\uuuuuuu

我想你真正的
FancyDict
已经实现了这些



ruamel.yaml是一个支持yaml 1.2的yaml库(我建议使用它,但我是这个包的作者)。PyYAML只支持(大部分)yaml1.1。更麻烦的是,它有不同的Python2和Python3的
constructor.py
文件,因此您可能无法在PyYAML中插入上述代码。

我找到了一个在PyYAML上实际工作的解决方案

class Loader(yaml.FullLoader):

    def construct_yaml_map(self, node):
        data = MyDictionaryClass()
        yield data
        value = self.construct_mapping(node)
        data.update(value)

Loader.add_constructor(
    'tag:yaml.org,2002:map',
    Loader.construct_yaml_map
)

使用中的解决方案的问题是PyYaml将映射转换回
construct\u yaml\u map
函数上的字典。仅在子类中替换此函数是不够的,因为为SafeLoader添加了自定义的
add\u构造函数
,因此您可以覆盖它,以便为您的类使用新的
Construction\u yaml\u映射。

感谢详细的回答抱歉没有更快地回答;-)
class Loader(yaml.FullLoader):

    def construct_yaml_map(self, node):
        data = MyDictionaryClass()
        yield data
        value = self.construct_mapping(node)
        data.update(value)

Loader.add_constructor(
    'tag:yaml.org,2002:map',
    Loader.construct_yaml_map
)