如何使用Python根据嵌套Key路径修改JSON文件指定值?
实现通过嵌套Key路径修改JSON文件的值
我需要用Python实现根据给定的嵌套Key路径(比如["payload","ServiceConfiguration", "TokenSettings", "ClientId"])修改JSON文件里的对应值。目前已经能用直接链式索引(比如superHeroSquad['payload']['ServiceConfiguration']['TokenSettings']['ClientId'] = "text")完成修改,但没法通过Key路径数组的方式实现。我尝试写递归方法但没成功,计划的实现步骤是:
- 方法1接收Key路径数组和文件名两个参数
- 把JSON文件内容加载成Python字典
- 调用递归方法,传入目标Key和字典,递归遍历直到定位到下游目标Key并更新其值
相关JSON示例
{ "payloadFormatVersion": "9.0", "payload": { "ServiceConfiguration": { "LoggingSettings": { "NumberOfLogFilesToKeep": 7, "LogFileSizeBytes": 0, "LogFolderPath": "C:\\demo\\logs\\feature\\", "EnvironmentType": "testingenv", "DataRelayLogSink": { "PeriodInSeconds": 60, "TargetAddress": "http://localhost:portNumber/dumm1", "TargetTokenAddress": "http://localhost:portnumber/token", "PayloadType": "somedata", "TokenCredentials": { "ClientId": "testclientid", "ClientSecret": "testclientsecret", "GrantType": "testgranttype" } } } } } }
现有尝试的代码片段
def repalcejsonForSpecificKey(keyPath,fileName): filePath = "C:\\rajesh\\Configurations\\" + fileName + "\\" + fileName + ".json" print(filePath) Dict = {} with open(filePath) as f: superHeroSquad = json.load(f) duplicatedict={} duplicatedict=superHeroSquad testDict=getDictonaryItems(keyPath[0],**superHeroSquad) print(testDict)
def getDictonaryItems(searchKey, duplicatedict): if searchKey in duplicatedict.keys(): testDict = duplicatedict[searchKey] return testDict
keyPath = ["payload","ServiceConfiguration", "TokenSettings", "ClientId"] fileName="vestas.sdh.dr.gateway" repalcejsonForSpecificKey(keyPath,fileName)
解决方案
现有代码仅处理了Key路径的第一个元素,未实现完整的路径遍历和值更新逻辑,以下提供两种可行实现方式:
方式1:迭代遍历实现(更直观)
通过迭代逐步定位到目标Key的父节点,最后修改目标值:
import json def replace_json_value(key_path, file_name, new_value): # 构建文件路径 file_path = f"C:\\rajesh\\Configurations\\{file_name}\\{file_name}.json" # 加载JSON为字典 with open(file_path, 'r') as f: data = json.load(f) # 遍历路径直到倒数第二个Key,定位父节点 current_node = data for key in key_path[:-1]: if key not in current_node: raise ValueError(f"路径中的Key '{key}'不存在") current_node = current_node[key] # 更新目标Key的值 target_key = key_path[-1] if target_key not in current_node: raise ValueError(f"目标Key '{target_key}'不存在") current_node[target_key] = new_value # 写回修改后的JSON文件 with open(file_path, 'w') as f: json.dump(data, f, indent=4) # 使用示例(注意对应实际JSON结构修正路径) key_path = ["payload","ServiceConfiguration", "LoggingSettings", "DataRelayLogSink", "TokenCredentials", "ClientId"] file_name = "vestas.sdh.dr.gateway" replace_json_value(key_path, file_name, "new_client_id_123")
方式2:递归遍历实现
按计划通过递归完成路径遍历和值更新:
import json def traverse_update(current_data, key_path, new_value, index=0): if index == len(key_path) - 1: # 到达目标Key,执行更新 if key_path[index] not in current_data: raise ValueError(f"目标Key '{key_path[index]}'不存在") current_data[key_path[index]] = new_value return # 递归进入下一层节点 next_key = key_path[index] if next_key not in current_data: raise ValueError(f"路径中的Key '{next_key}'不存在") traverse_update(current_data[next_key], key_path, new_value, index + 1) def replace_json_value_recursive(key_path, file_name, new_value): file_path = f"C:\\rajesh\\Configurations\\{file_name}\\{file_name}.json" with open(file_path, 'r') as f: data = json.load(f) traverse_update(data, key_path, new_value) # 写回文件 with open(file_path, 'w') as f: json.dump(data, f, indent=4) # 使用示例 key_path = ["payload","ServiceConfiguration", "LoggingSettings", "DataRelayLogSink", "TokenCredentials", "ClientId"] file_name = "vestas.sdh.dr.gateway" replace_json_value_recursive(key_path, file_name, "recursive_new_client_id")
注意事项
- 注意Key路径的准确性:示例JSON中不存在
TokenSettings,实际有效路径需对应JSON结构调整 - 写回文件时添加
indent=4可保持JSON格式的可读性 - 代码中加入了Key不存在的异常处理,避免程序无提示崩溃
内容的提问来源于stack exchange,提问作者rajesh
相关产品推荐
相关产品推荐

