Python中替换JSON文件内同名多字段的问题
问题:JSON文件中重复字段仅能修改第二个的解决方法
我尝试修改JSON文件,但仅成功修改了第二个同名字段,第一个字段完全没有变化。
我的代码如下:
with open(os.path.join(model_folder, 'config.json'), 'r') as f: config = json.load(f) config['speakers_file'] = os.path.join('model', 'speaker_ids', 'speakers.pth') config['embeddings_file'] = [os.path.join('embeddings', 'corpus_speakers.pth'), os.path.join('embeddings', 'train_speakers.pth')] with open(os.path.join(model_folder, 'config.json'), 'w') as f: json.dump(config, f, indent=4)
工具自动生成的原始config内容:
"speakers_file": "/home/username/pathinmymachine/modelrunfolder/speakers.pth", "embeddings_file": [ "/home/username/pathinmymachine/corpusfolder/speakers.pth", "speakers.pth" "speakers_file": "/home/username/pathinmymachine/modelrunfolder/speakers.pth", "embeddings_file": [ "/home/username/pathinmymachine/corpusfolder/speakers.pth", "speakers.pth"
我期望修改后的结果:
"speakers_file": "model/speaker_ids/speakers.pth", "embeddings_file": [ "embeddings/corpus_speakers.pth", "embeddings/train_speakers.pth" "speakers_file": "model/speaker_ids/speakers.pth", "embeddings_file": [ "embeddings/corpus_speakers.pth", "embeddings/train_speakers.pth"
实际得到的结果:
"speakers_file": "/home/username/pathinmymachine/modelrunfolder/speakers.pth", "embeddings_file": [ "/home/username/pathinmymachine/corpusfolder/speakers.pth", "speakers.pth" "speakers_file": "model/speaker_ids/speakers.pth", "embeddings_file": [ "embeddings/corpus_speakers.pth", "embeddings/train_speakers.pth"
核心原因
JSON规范不允许对象中存在重复键,Python标准库的json.load()在解析这种不规范JSON时,会自动保留最后一个重复键的值,前面的键值对会被直接覆盖。因此你读取到的config字典里只有最后一组speakers_file和embeddings_file,修改自然只影响最后一个。
解决方法
方法一:直接文本替换(适合结构固定的场景)
跳过JSON解析,直接读取文件内容为字符串,进行精准替换,避免解析时丢失重复键。
import os file_path = os.path.join(model_folder, 'config.json') # 读取原始文件内容 with open(file_path, 'r') as f: content = f.read() # 替换speakers_file字段值 content = content.replace( '"speakers_file": "/home/username/pathinmymachine/modelrunfolder/speakers.pth"', '"speakers_file": "model/speaker_ids/speakers.pth"' ) # 替换embeddings_file字段值 content = content.replace( '"embeddings_file": [\n "/home/username/pathinmymachine/corpusfolder/speakers.pth",\n "speakers.pth"', '"embeddings_file": [\n "embeddings/corpus_speakers.pth",\n "embeddings/train_speakers.pth"' ) # 写入修改后的内容 with open(file_path, 'w') as f: f.write(content)
注意:这种方法要求原始文本的格式(空格、换行、引号)完全匹配,否则替换会失效。
方法二:使用支持重复键的JSON解析库
使用第三方库demjson,它可以解析包含重复键的JSON,并保留所有键值对的顺序。
- 先安装库:
pip install demjson
- 修改代码:
import os import demjson file_path = os.path.join(model_folder, 'config.json') # 解析JSON,保留重复键和顺序 with open(file_path, 'r') as f: config = demjson.decode(f.read(), preserve_order=True) # 遍历所有键,修改所有匹配的字段 for key in list(config.keys()): if key == 'speakers_file': config[key] = 'model/speaker_ids/speakers.pth' elif key == 'embeddings_file': config[key] = ['embeddings/corpus_speakers.pth', 'embeddings/train_speakers.pth'] # 写回文件,保持格式缩进 with open(file_path, 'w') as f: demjson.encode_to_file(f, config, indent=4)
内容的提问来源于stack exchange,提问作者badner
相关产品推荐
相关产品推荐

