如何在Python加载YAML文件时解析内部变量引用?
解析YAML文件中的变量引用
默认的yaml.safe_load不会处理${xxx}格式的变量引用,以下两种方法可以实现变量解析:
方法一:手动递归替换变量
无需额外依赖,通过递归遍历YAML数据,识别并替换变量引用。
import yaml from typing import Dict, Any def resolve_vars(data: Dict[str, Any], root: Dict[str, Any]) -> Dict[str, Any]: resolved = {} for key, val in data.items(): if isinstance(val, dict): resolved[key] = resolve_vars(val, root) elif isinstance(val, str) and val.startswith("${") and val.endswith("}"): # 拆分变量路径,如"download.input_data_dir"转为列表 path_parts = val[2:-1].split(".") current = root try: for part in path_parts: current = current[part] resolved[key] = current except KeyError: # 变量不存在时保留原始值,也可抛出异常 resolved[key] = val else: resolved[key] = val return resolved # 加载原始YAML with open("../params.yaml", "r") as f: raw_params = yaml.safe_load(f) # 解析变量 params = resolve_vars(raw_params, raw_params) # 验证结果 print(params['prepare']['input_dir']) # 输出: ./data/input print(params['process']['output_dir']) # 输出: ./output/1
方法二:使用Jinja2模板引擎预渲染
借助Jinja2的模板渲染能力,先替换变量再加载YAML,适合复杂场景。
首先安装依赖:
pip install jinja2
代码示例:
import yaml from jinja2 import Environment, BaseLoader # 读取YAML文件内容 with open("../params.yaml", "r") as f: yaml_content = f.read() # 加载原始数据作为渲染上下文 with open("../params.yaml", "r") as f: raw_params = yaml.safe_load(f) # 配置Jinja2使用${}作为变量分隔符 env = Environment(loader=BaseLoader(), variable_start_string="${", variable_end_string="}") template = env.from_string(yaml_content) # 渲染替换变量 rendered_content = template.render(**raw_params) # 加载渲染后的YAML params = yaml.safe_load(rendered_content) # 验证结果 print(params['prepare']['input_dir']) # 输出: ./data/input print(params['process']['output_dir']) # 输出: ./output/1
内容的提问来源于stack exchange,提问作者raj
相关产品推荐
相关产品推荐

