如何用Python的ruamel库添加数组元素及批量修改YAML多环境配置
问题1:如何使用Python的ruamel库为数组添加新元素?
ruamel.yaml最贴心的一点就是能保留原YAML文件的格式、注释和缩进,所以添加数组元素的时候,只要像操作普通Python列表那样处理就行,关键是保存时要复用原文件的格式信息。
举个实际例子:假设你有一个fruits.yaml文件,内容是:
fruits: - apple - banana # 这是个注释,希望保留
你可以用下面的代码给fruits数组添加新元素:
from ruamel.yaml import YAML from ruamel.yaml.util import load_yaml_guess_indent # 加载YAML文件,同时获取原文件的缩进和块序列缩进信息 yaml = YAML() with open('fruits.yaml', 'r') as f: config, ind, bsi = load_yaml_guess_indent(f) # 直接用Python列表的方法添加元素——append是加到末尾,insert可以指定位置 config['fruits'].append('orange') # 如果想插到第一个位置:config['fruits'].insert(0, 'grape') # 保存文件时复用原格式,确保注释、缩进都不变 with open('fruits.yaml', 'w') as f: yaml.indent(mapping=ind, sequence=ind, offset=bsi) yaml.dump(config, f)
运行后,你的fruits.yaml会变成:
fruits: - apple - banana - orange # 这是个注释,希望保留
完全保留了原文件的注释和缩进风格~
问题2:修改支持多环境的YAML配置文件
你的原代码只处理单环境,要扩展到多环境,核心是修改参数处理逻辑,让程序能解析多组环境配置,然后逐个更新。先假设你的Jenkinsfile.yaml结构大概是这样的(如果结构不同,你可以调整代码里的路径):
deploy_config: dev: image_tag: v1.0.0 replicas: 2 prod: image_tag: v1.0.0 replicas: 4
下面是修改后的代码,支持传入多个环境的配置参数(比如运行python sample.py dev=v1.1.0 prod=v1.1.0 test=v1.2.0):
import ruamel.yaml import sys from ruamel.yaml.util import load_yaml_guess_indent file_name = 'Jenkinsfile.yaml' # 加载配置和原文件格式信息 config, ind, bsi = load_yaml_guess_indent(open(file_name)) # 处理传入的命令行参数:预期参数是「环境名=配置值」的格式 args = sys.argv[1:] updated_count = 0 for arg in args: # 先检查参数格式是否合法 if '=' not in arg: print(f"⚠️ 无效参数:{arg},请使用「环境名=值」的格式") sys.exit(1) # 拆分环境名和对应的值(只拆一次,避免值里包含=的情况) env_name, env_value = arg.split('=', 1) # 如果环境不存在,自动创建新环境节点(不需要的话可以删掉这段判断) if env_name not in config['deploy_config']: config['deploy_config'][env_name] = {'image_tag': env_value, 'replicas': 1} print(f"✅ 已添加新环境:{env_name}") else: # 修改现有环境的配置(这里假设是修改image_tag,你可以换成自己需要的键) config['deploy_config'][env_name]['image_tag'] = env_value print(f"✅ 已更新环境:{env_name}") updated_count += 1 # 保存修改后的配置,保留原格式 yaml = ruamel.yaml.YAML() yaml.indent(mapping=ind, sequence=ind, offset=bsi) with open(file_name, 'w') as f: yaml.dump(config, f) print(f"\n🎉 操作完成,共处理 {updated_count} 个环境")
几点说明:
- 参数灵活性:用
split('=', 1)拆分参数,即使值里包含=(比如dev=v1.1.0-build=123)也能正确处理。 - 容错性:添加了参数格式检查,避免非法参数导致程序崩溃。
- 格式保留:依然用
load_yaml_guess_indent获取原文件的缩进信息,保存时复用,保证YAML文件的格式和原文件一致。 - 可扩展性:如果你的YAML结构是数组形式的环境(比如
environments: [{name: dev, tag: v1.0}, ...]),可以改成遍历数组查找对应name的元素,或者添加新的字典到数组里,比如:# 假设环境是数组结构 new_env = {'name': 'test', 'image_tag': 'v1.2.0'} config['environments'].append(new_env)
内容的提问来源于stack exchange,提问作者Mitul
相关产品推荐
相关产品推荐

