Python实现多层级JSON配置文件变量键替换方案问询
解决多层级配置变量替换的通用方案
你的需求很典型——用settings作为全局变量池,让整个配置(包括嵌套对象、数组,甚至未来新增的层级)都能动态引用这些变量,避免重复修改路径。之前的单层级代码只能处理最外层的字符串,没法搞定嵌套结构,我们可以用递归遍历+变量映射的方式来实现通用解决方案。
核心思路
- 先从
settings中提取变量映射表,把$general这种占位符和对应的实际值关联起来; - 写一个递归处理函数,针对不同类型的数据做差异化处理:
- 字符串:替换所有匹配的变量占位符
- 字典:遍历每个键值对,递归处理值
- 列表:遍历每个元素,递归处理元素
- 用这个函数处理整个配置(注意跳过
settings本身,避免变量池被意外修改)
完整实现代码
import re def replace_variables(data, var_map): # 处理字符串:替换所有匹配的变量 if isinstance(data, str): # 用正则精准匹配$开头的变量名,避免误替换类似$generalxxx的非预期内容 pattern = re.compile(r'\$(\w+)') return pattern.sub(lambda match: var_map.get(f"${match.group(1)}", match.group(0)), data) # 处理字典:递归遍历每个值 elif isinstance(data, dict): return {key: replace_variables(value, var_map) for key, value in data.items()} # 处理列表:递归遍历每个元素 elif isinstance(data, list): return [replace_variables(item, var_map) for item in data] # 其他类型(数字、布尔等)直接返回不修改 else: return data # 你的原始配置 config = { "settings": { "general": "root", "folder": "folder_test" }, "TEST1": { "dataone": "xyz", "testing": { "a": "$general/$folder/test.png", "b": "$general/$folder/test.png" }, "SOMELIST": [ "$general/$folder/test.png", "$general/$folder/test.png" ] }, "TEST2": { "dataone": "xyz", "testing": { "a": "$general/$folder/test.png", "b": "$general/$folder/test.png" }, "something": { "test_data": { "tester": { "abc": "$general/$folder/test.png", "zxv": "$general/$folder/test.png" } } } } } # 构建变量映射表:$变量名 -> 实际值 var_map = {f"${k}": v for k, v in config['settings'].items()} # 处理配置(保留原始settings,只替换其他部分) processed_config = { "settings": config['settings'], **{key: replace_variables(value, var_map) for key, value in config.items() if key != "settings"} } # 打印处理后的结果(格式化输出更清晰) import json print(json.dumps(processed_config, indent=2))
代码细节说明
- 正则替换:用
r'\$(\w+)'确保只匹配独立的变量名,不会把$general123这类字符串误拆分成变量; - 递归适配:不管嵌套多少层的字典或数组,函数都会深入到最底层的字符串进行替换,未来新增的层级只要符合现有结构就能自动适配;
- 容错处理:如果遇到未定义的变量(比如
$undefined),会保留原始占位符,不会破坏配置结构;
处理后的效果
运行代码后,所有$general/$folder/test.png都会被替换成root/folder_test/test.png,包括TEST2里嵌套四层的tester字段、TEST1里的数组元素,完全覆盖你需求中的所有场景。
内容的提问来源于stack exchange,提问作者user1897151
相关产品推荐
相关产品推荐

