使用ruamel.yaml解析YAML注释 实现注释与对应变量的正确关联
问题根因
ruamel.yaml 的往返(RoundTrip)加载器默认规则下,YAML 文档起始标记 --- 之后、第一个键之前的注释会被识别为全局文档起始注释,存储在 loaded.ca.start 属性中,不会归属到第一个键的注释映射里,这就是你遇到首条注释归属异常的原因。
适配方案
可以通过简单的自定义转换函数实现你需要的注释归属效果,不会破坏原有YAML的格式,回写文件时也能完全保留原有排版:
步骤1:定义注释转换函数
from ruamel.yaml.tokens import CommentToken def adjust_first_key_comment(loaded_yaml): # 仅当存在全局起始注释、且加载结果为键值对结构时执行转换 if loaded_yaml.ca.start and loaded_yaml.ca.start[1] and isinstance(loaded_yaml, dict): # 取第一个键 first_key = next(iter(loaded_yaml.keys())) # 提取起始注释 token start_comment = loaded_yaml.ca.start[1][0] # 初始化第一个键的注释槽位 if first_key not in loaded_yaml.ca.items: loaded_yaml.ca.items[first_key] = [None, None, None, None] # 将全局注释赋值给第一个键的前置注释位置 loaded_yaml.ca.items[first_key][2] = start_comment # 清空全局起始注释 loaded_yaml.ca.start = [None, None]
步骤2:在加载流程中调用
在你原有加载代码后新增一行调用即可:
from ruamel.yaml import YAML yaml = YAML() yaml.preserve_quotes = True yaml.explicit_start = True with open('my_file.yml', 'r', encoding='utf-8') as f: loaded = yaml.load(f) # 执行注释结构调整 adjust_first_key_comment(loaded) # 此时输出的ca结构就符合你的预期 print(loaded.ca)
补充说明
如果需要将调整后的内容回写至YAML文件,直接调用yaml.dump(loaded, open('my_file.yml', 'w', encoding='utf-8'))即可,原有注释位置、引号规则、列表格式都会完整保留,不会出现格式改动。
内容的提问来源于stack exchange,提问作者albertoperdomo2
相关产品推荐
相关产品推荐

