使用Python处理YAML文件后结构错乱、注释丢失的原因排查
问题原因解析
1. 键顺序变更
Python标准库的yaml.safe_load会把YAML的键值对映射解析为普通Python字典。在Python 3.7之前,字典是无序结构;即便3.7+版本字典保留插入顺序,yaml.safe_dump默认也不会遵循原始YAML的键顺序输出,而是按自身规则排序,导致trigger等键的位置发生偏移。
2. 注释丢失
包括pyyaml的safe_load在内的常规YAML解析器,会将注释视为非数据的格式内容,解析时直接忽略,不会将其存入解析后的Python对象中,因此重新序列化时无法还原任何注释。
3. 层级结构错乱
原始YAML中stages下的stage是映射的第一个键,但解析为字典后,yaml.safe_dump输出时改变了键的顺序,导致jobs排在stage之前,出现结构排版错乱。另外,原始空值的job:被解析为None,dump后显示为job: null,也属于解析-序列化过程中的格式丢失。
修复方案
要保留YAML的原始格式、键顺序和注释,推荐使用ruamel.yaml库,它专门针对YAML的编辑场景设计,支持保留原始结构信息。
修复后的脚本
from ruamel.yaml import YAML core_repos = ["REPO1", "REPO2"] if __name__ == "__main__": yml_file_name = "azure-pipelines.yml" yaml = YAML() # 保留引号、缩进等原始格式 yaml.preserve_quotes = True yaml.indent(mapping=2, sequence=4, offset=2) with open(yml_file_name, 'r') as yml_file: yml_content = yaml.load(yml_file) # 过滤目标仓库 resources = yml_content.get("resources", {}) repositories = resources.get("repositories", []) filtered_repos = [repo for repo in repositories if repo.get("repository") in core_repos] resources["repositories"] = filtered_repos with open(yml_file_name, 'w') as f: yaml.dump(yml_content, f)
使用说明
- 先安装依赖库:
pip install ruamel.yaml - 该脚本会保留原始YAML的注释、键顺序、缩进和引号格式,仅过滤掉不在
core_repos列表中的仓库项。
内容的提问来源于stack exchange,提问作者Rattletrap
相关产品推荐
相关产品推荐

