You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不解析锚点值的情况下导出YAML内容?

问题描述

我有如下YAML文件:

anchor1: &anchor1
  resource_class: small

anchor2: &anchor2
  hello: world

anchor3: &anchor3
  hello: world

root1:
  nested1:
    <<: *anchor1
    some_list:
      - item1:
          hello: world
      - *anchor2
      - *anchor3

  nested2:
    <<: *anchor1
    some_list:
      - item1:
          hello: world
      - *anchor2
      - *anchor3

  nested3:
    <<: *anchor1
    some_list:
      - item1:
          hello: world
      - *anchor2
      - *anchor3


root2:
  nested1:
    <<: *anchor1
    some_list:
      - item1:
          hello: world2
      - *anchor2
      - *anchor3

...

我想要将nested1的值提取到单独文件中,且不解析所有锚点。使用如下代码:

from pathlib import Path
from ruamel.yaml import YAML

yaml = YAML()
with open(Path('in_file')) as f:
    data = yaml.load(f)

with open(Path('out_file'), 'w') as f:
    yaml.dump(data['root1']['nested1'], f)

期望导出的输出为:

<<: *anchor1
some_list:
  - item1:
      hello: world
  - *anchor2
  - *anchor3

我知道这是无效YAML(缺少锚点定义),但核心需求是保留锚点引用而非展开内容。目前遇到的问题是:提取子节点后,锚点已被自动解析合并,导出的是展开后的数据;但如果dump整个文件,锚点引用能正常保留。推测是因为锚点定义不在data['root1']的范围内,但不知道如何解决。

解决方案

问题出在默认加载模式下,ruamel.yaml会自动解析合并锚点内容,丢失原始的引用标记。要保留锚点引用,需要使用round trip模式加载YAML,该模式会完整保留原始的结构、锚点、注释等信息。

修改后的代码如下:

from pathlib import Path
from ruamel.yaml import YAML

# 使用round trip模式初始化YAML对象
yaml = YAML(typ='rt')
yaml.preserve_quotes = True  # 可选,保留原始引号格式

with open(Path('in_file')) as f:
    data = yaml.load(f)

# 提取目标节点
target_node = data['root1']['nested1']

with open(Path('out_file'), 'w') as f:
    yaml.dump(target_node, f)
原理说明

round trip模式(typ='rt')是ruamel.yaml专为保留YAML原始格式设计的模式,它会:

  • 保留锚点(&anchor)和引用(*anchor)的原始结构,不会自动合并展开
  • 保留注释、换行、引号等格式细节
  • 用特殊的字典类型(如CommentedMap、MergeKeyDict)存储节点,记录原始的合并操作(<<: *anchor)

这样dump目标子节点时,就能输出期望的锚点引用格式,而不是展开后的内容。

内容的提问来源于stack exchange,提问作者doodla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:23:31