使用Python在YAML中获取重复密钥

使用Python在YAML中获取重复密钥,第1张

使用Python在YAML中获取重复密钥

PyYAML只会默默覆盖第一个条目,ruamel.yaml¹将为

DuplicateKeyFutureWarning
if(如果与旧版API一起使用),并
DuplicateKeyError
为新API提出一个。

如果您不想

Constructor
为所有类型创建一个全数,
SafeConstructor
则应覆盖其中的映射构造函数来完成此工作:

    import sys    from ruamel.yaml import YAML    from ruamel.yaml.constructor import SafeConstructor    yaml_str = """    build:      step: 'step1'    build:      step: 'step2'    """    def construct_yaml_map(self, node):        # test if there are duplicate node keys        data = []        yield data        for key_node, value_node in node.value: key = self.construct_object(key_node, deep=True) val = self.construct_object(value_node, deep=True) data.append((key, val))    SafeConstructor.add_constructor(u'tag:yaml.org,2002:map', construct_yaml_map)    yaml = YAML(typ='safe')    data = yaml.load(yaml_str)    print(data)

这使:

[('build', [('step', 'step1')]), ('build', [('step', 'step2')])]

但是,似乎没有必要将

step:'step1'
其列入列表。以下仅在有重复项的情况下创建列表(可以通过缓存的结果进行优化,如有必要
self.construct_object(key_node,deep=True)
):

    def construct_yaml_map(self, node):        # test if there are duplicate node keys        keys = set()        for key_node, value_node in node.value: key = self.construct_object(key_node, deep=True) if key in keys:     break keys.add(key)        else: data = {}  # type: Dict[Any, Any] yield data value = self.construct_mapping(node) data.update(value) return        data = []        yield data        for key_node, value_node in node.value: key = self.construct_object(key_node, deep=True) val = self.construct_object(value_node, deep=True) data.append((key, val))

这使:

[('build', {'step': 'step1'}), ('build', {'step': 'step2'})]

一些要点:

  • 可能无需多说,这不适用于YAML合并键(
    <<: *xyz
  • 如果您需要ruamel.yaml的往返功能(
    yaml = YAML()
    ),则需要更复杂的功能
    construct_yaml_map
  • 如果要转储输出,则应
    YAML()
    为此实例化一个新实例,而不是重新使用用于加载的“已修补”实例(这可能会起作用,这是可以肯定的):
    yaml_out = YAML(typ='safe')

    yaml_out.dump(data, sys.stdout)

给出(与第一个

construct_yaml_map
):

    - - build  - - [step, step1]- - build  - - [step, step2]
  • 在PyYAML或ruamel.yaml中不起作用的是
    yaml.load('file.yml')
    。如果您不想
    open()
    自己归档文件,则可以执行以下 *** 作:
        from pathlib import Path  # or: from ruamel.std.pathlib import Path    yaml = YAML(typ='safe')    yaml.load(Path('file.yml')

¹免责声明:我是该软件包的作者。



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5674598.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存