PyYAML只会默默覆盖第一个条目,ruamel.yaml¹将为
DuplicateKeyFutureWarningif(如果与旧版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')
¹免责声明:我是该软件包的作者。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)