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

Python修改YAML值时保留锚点(Anchor)的实现方法

如何修改YAML锚点对应值并保留锚点(ruamel.yaml)

问题场景

我有一个带锚点和别名的YAML文件,内容如下:

dev:
    value1: &dev-value1 "value1"
    value2: &dev-value2 "value2"

test:
    value1: *dev-value1
    value2: *dev-value2

想要修改dev/value1的值,同时保留其锚点&dev-value1,让test/value1的别名依然指向修改后的值。但用普通赋值的脚本执行后,锚点丢失,生成的文件不符合预期。

原脚本

import ruamel.yaml
yaml = ruamel.yaml.YAML()

with open("test.eyaml") as eyaml_file:
    data = yaml.load(eyaml_file)

    data["dev"]["value1"] = "new_value"
with open("new.eyaml", "w") as new_eyaml_file:
    yaml.dump(data, new_eyaml_file)

错误输出

脚本执行后,锚点跑到了test/value1上,dev/value1的锚点丢失:

dev:
  value1: new_value
  value2: &dev-value2 value2

test:
  value1: &dev-value1 value1
  value2: *dev-value2

期望输出

希望修改后锚点仍保留在dev/value1,且别名正确指向新值:

dev:
    value1: &dev-value1 "new_value"
    value2: &dev-value2 "value2"

test:
    value1: *dev-value1
    value2: *dev-value2

解决方案

ruamel.yaml加载YAML后,锚点对应的是节点对象,直接赋值会替换节点,破坏锚点关联。需要直接修改原节点的value属性,同时保留锚点信息:

修改后的脚本

import ruamel.yaml
from ruamel.yaml.scalarstring import DoubleQuotedScalarString

yaml = ruamel.yaml.YAML()
# 设置和原文件一致的缩进格式
yaml.indent(mapping=4, sequence=4, offset=2)

with open("test.eyaml") as eyaml_file:
    data = yaml.load(eyaml_file)
    
    # 获取dev/value1对应的节点对象,直接修改其值
    dev_value1_node = data["dev"]["value1"]
    # 用DoubleQuotedScalarString确保新值带双引号,和原格式匹配
    dev_value1_node.value = DoubleQuotedScalarString("new_value")

with open("new.eyaml", "w") as new_eyaml_file:
    yaml.dump(data, new_eyaml_file)

说明

  1. 保留锚点:直接操作原节点的value属性,不会破坏节点上绑定的锚点信息,锚点&dev-value1会保留在dev/value1位置。
  2. 格式匹配:通过yaml.indent()设置和原文件一致的缩进参数,保证输出格式和原文件对齐。
  3. 引号控制:使用DoubleQuotedScalarString包裹新值,确保输出带双引号,和原格式一致;如果需要单引号,可改用SingleQuotedScalarString。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:05:11