使用ruamel.yaml修改YAML后输出丢失注释的问题
解决ruamel.yaml修改YAML后注释丢失的问题
用ruamel.yaml加载带注释的YAML文件,改完字段值再写回去,结果注释全没了——字段更新、引号缩进都正常,就是注释丢了,这情况怎么处理?
你的原始代码
import ruamel.yaml source = open("source.yaml", "r") target = open("target.yaml", "r") sourceValues = ruamel.yaml.load(source, ruamel.yaml.RoundTripLoader, preserve_quotes=True) targetValues = ruamel.yaml.load(target, ruamel.yaml.RoundTripLoader, preserve_quotes=True) source.close() target.close() # 修改target的属性 targetValues['test']['something'] = sourceValues['test']['something'] with open('target.yaml', 'w') as conf: ruamel.yaml.dump(targetValues, conf, ruamel.yaml.RoundTripDumper)
原始带注释的YAML(target.yaml)
test: # some comment something: "something" # another comment else: 123
执行后的输出
test: something: "something-updated" else: 123456
为啥会丢注释?
你直接用targetValues['test']['something'] = ...赋值的时候,是把原来的节点对象整个替换掉了。ruamel.yaml的RoundTripLoader加载出来的节点里是带着注释信息的,一替换,这些注释数据就被扔了,自然写回去的时候没注释。
怎么解决?
别直接替换节点,只修改原有节点的value属性就行,这样注释会跟着保留。另外建议用with语句管文件,不用手动close,更省心。
修改后的代码:
import ruamel.yaml # 用with自动处理文件关闭 with open("source.yaml", "r") as source, open("target.yaml", "r") as target: sourceValues = ruamel.yaml.load(source, ruamel.yaml.RoundTripLoader, preserve_quotes=True) targetValues = ruamel.yaml.load(target, ruamel.yaml.RoundTripLoader, preserve_quotes=True) # 只改节点的值,原节点的注释不动 targetValues['test']['something'].value = sourceValues['test']['something'].value with open('target.yaml', 'w') as conf: # dump的时候加上preserve_quotes,确保引号格式不变 ruamel.yaml.dump(targetValues, conf, ruamel.yaml.RoundTripDumper, preserve_quotes=True)
额外补充
如果要手动加注释或者调整注释,可以用ruamel.yaml的专用API:
# 在something字段前面加注释 targetValues['test'].yaml_set_comment_before_key('something', '# some comment') # 给something字段加行尾注释 targetValues['test']['something'].yaml_add_eol_comment('another comment', column=20)
内容的提问来源于stack exchange,提问作者Ventrue
相关产品推荐
相关产品推荐

