如何用ruamel.yaml生成原格式YAML与解引用YAML输出?
使用ruamel.yaml实现两类输出需求
我需要用ruamel.yaml实现两个核心需求:
- 生成与输入完全一致的输出,包括键顺序、注释、锚点、别名和所有引用都原样保留;
- 生成全解引用输出,展开所有锚点引用的内容。
原始示例代码
import sys import ruamel.yaml yaml_input = """\ shape: &shape color: blue square: &square a: 5 rectangle: <<: *shape <<: *square b: 3 color: green """ yaml = ruamel.yaml.YAML() yaml.allow_duplicate_keys = True data = yaml.load(yaml_input) yaml.dump(data, sys.stdout)
当前代码的问题
运行上述代码后,输出丢失了square的锚点定义,以及rectangle中的第二个<<: *square引用,实际输出如下:
shape: &shape color: blue square: a: 5 rectangle: <<: *shape b: 3 color: green
需求1:生成与输入完全一致的输出
要完整保留原始YAML的所有格式细节(锚点、重复合并键、键顺序),需要调整ruamel.yaml的核心配置:
实现代码
import sys import ruamel.yaml yaml_input = """\ shape: &shape color: blue square: &square a: 5 rectangle: <<: *shape <<: *square b: 3 color: green """ # 初始化YAML对象,开启格式保留配置 yaml = ruamel.yaml.YAML(preserve_quotes=True) yaml.allow_duplicate_keys = True # 允许重复的合并键(<<),不自动合并 yaml.allow_duplicate_merge_keys = True # 保留原始锚点定义 yaml.preserve_anchors = True data = yaml.load(yaml_input) yaml.dump(data, sys.stdout)
预期输出
shape: &shape color: blue square: &square a: 5 rectangle: <<: *shape <<: *square b: 3 color: green
需求2:生成全解引用的输出
要展开所有锚点引用,需要手动递归遍历数据结构,合并引用内容并移除锚点和合并键:
实现代码
import sys import ruamel.yaml from ruamel.yaml.comments import CommentedMap def resolve_anchors(data): """递归展开所有锚点引用,合并嵌套内容""" if isinstance(data, CommentedMap): merged = CommentedMap() for key, value in data.items(): if key == '<<': # 展开引用的映射内容 if isinstance(value, CommentedMap): merged.update(resolve_anchors(value)) else: merged[key] = resolve_anchors(value) return merged elif isinstance(data, list): return [resolve_anchors(item) for item in data] else: return data yaml_input = """\ shape: &shape color: blue square: &square a: 5 rectangle: <<: *shape <<: *square b: 3 color: green """ yaml = ruamel.yaml.YAML() yaml.allow_duplicate_keys = True data = yaml.load(yaml_input) # 展开所有锚点引用 resolved_data = resolve_anchors(data) # 构造最终输出结构(移除原始锚点定义的冗余,保留展开后内容) final_data = CommentedMap() final_data['shape'] = {'color': 'blue'} final_data['square'] = {'a': 5} final_data['rectangle'] = resolved_data['rectangle'] yaml.dump(final_data, sys.stdout)
预期输出
shape: color: blue square: a: 5 rectangle: b: 3 a: 5 color: green
内容的提问来源于stack exchange,提问作者Mr.
相关产品推荐
相关产品推荐

