如何为创建自定义yaml映射转储程序阿默尔·亚姆?

2024-06-25 23:19:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为一些配置对象定制一个YAML转储器/加载程序。为了简单起见,假设我们要将Hero类的对象转储到hero.yml文件中。在

使用默认转储器/装载器的示例

class Hero:
    yaml_tag = '!Hero'
    def __init__(self, name, age):
        self.name = name
        self.age = age

然后通过ruamel.yaml添加默认的加载程序/转储程序

^{pr2}$

试着卸载:

h = Hero('Saber', 15)
with open('config.yml', 'w') as fout:
    yaml.dump(h, fout)
with open('config.yml') as fin:
    yaml.load(fin)

它工作得很好!在

但是使用自定义的to_yamlfrom_yaml方法失败

但是,当我需要一个更灵活的行为时,因此需要一个自定义的from_yaml和{}方法,就有问题了。在

Hero的实现更改为:

class Hero:
    yaml_tag = '!Hero'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def to_yaml(cls, representer, data):
        return representer.represent_mapping(cls.yaml_tag, 
                                             {'name': data.name, 'age': data.age})

    @classmethod
    def from_yaml(cls, constructor, node):
        print(node) # for debug
        value = constructor.construct_mapping(node)
        return cls(**value)

翻斗车工作正常。但是加载未能加载YAML文件。安 引发异常:

    243     def check_mapping_key(self, node, key_node, mapping, key, value):
    244         # type: (Any, Any, Any, Any, Any) -> None
--> 245         if key in mapping:
    246             if not self.allow_duplicate_keys:
    247                 args = [

TypeError: argument of type 'NoneType' is not iterable

通过标记为print(node)print(node)行,加载的节点是:

MappingNode(tag='!Hero', value=[(ScalarNode(tag='tag:yaml.org,2002:str', value='name'), ScalarNode(tag='tag:yaml.org,2002:str', value='Saber')), (ScalarNode(tag='tag:yaml.org,2002:str', value='age'), ScalarNode(tag='tag:yaml.org,2002:int', value='15'))])

不使用默认卸料机/装载机的原因

这个例子是一个很小的例子来说明这个问题,在真实的例子中,我试图只转储对象的一部分,比如

class A:
    yaml_tag = '!A'
    def __init__(self, name, age):
        self.data = {'name': name, 'age': age}

所需的A('Saber', 15)的YAML文件是

!A
name: Saber
age: 15

在这种情况下,我不知道如何使默认的卸载程序/装载程序工作。在

我的错误在哪里导致失败?如何解决这个问题?在


Tags: nameself程序nodeyamlagedatavalue
1条回答
网友
1楼 · 发布于 2024-06-25 23:19:29

RoundTripConstructor.construct_mapping的定义是:

def construct_mapping(self, node, maptyp=None, deep=False)

它需要知道它需要什么样的映射 构造。在旋转木马里有一些期待什么 可以附加到这样一个对象上,所以你最好模拟 RoundTripDumper过程中的例程:CommentedMap(一个普通的 dict不起作用)。在

所以你需要做一些事情,比如:

^{pr2}$

它给出了:

Hero(name -> Saber, age -> 15)

上面的工作原理是因为你的类相对简单,如果可以的话 递归部分,您需要遵循两步创建过程, 以创建对象的初始收益率,以便在递归过程中使用它。在

maptyp默认为None是历史的,它必须是 设置。E、 g.construct_mapping首先要做的事情之一是 正在尝试附加注释(如果节点上有可用的注释)。 我将删除0.15.55中的默认值,这将使 如果你像你一样漏掉了,那就错了。在

相关问题 更多 >