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