递归比对JSON文件差异未按预期输出及JSONDecodeError问题求解
问题根因
你当前的报错是因为混淆了json.load()和json.loads()的用法:
json.loads()接收的是JSON格式的字符串参数,你直接传文件名'sample1.json'字符串,自然会报解析失败的错误- 读取本地JSON文件需要用
json.load(),传入打开的文件对象
最高效实现方案
直接使用成熟的第三方库deepdiff,它本身就支持嵌套JSON的深度比对,自动识别新增、删除、修改的内容,不需要自己手写递归比对逻辑,能完美满足你的需求。
步骤1:安装依赖
pip install deepdiff
步骤2:完整代码
import json from deepdiff import DeepDiff # 正确读取两个JSON文件 with open('sample1.json', 'r', encoding='utf-8') as f: lhs = json.load(f) with open('sample2.json', 'r', encoding='utf-8') as f: rhs = json.load(f) # 执行比对 diff = DeepDiff(lhs, rhs, verbose_level=2) # 格式化输出差异 diff_count = 0 for changes in diff.values(): diff_count += len(changes) print(f"{diff_count} 处差异 found\n") for diff_type, changes in diff.items(): if diff_type == 'iterable_item_added': for path, value in changes.items(): print(f"路径{path}: 右侧新增内容:\n{json.dumps(value, indent=4, ensure_ascii=False)}") elif diff_type == 'dictionary_item_added': for path, value in changes.items(): print(f"路径{path}: 右侧新增字段:\n{json.dumps(value, indent=4, ensure_ascii=False)}") elif diff_type == 'values_changed': for path, change in changes.items(): print(f"路径{path}: 内容变更,左侧值为{change['old_value']},右侧值为{change['new_value']}") elif diff_type == 'iterable_item_removed': for path, value in changes.items(): print(f"路径{path}: 右侧删除内容:\n{json.dumps(value, indent=4, ensure_ascii=False)}")
运行输出示例
针对你提供的两个样例JSON,输出会清晰标注sample2比sample1多了两个完整的donut对象的差异:
2 处差异 found 路径root[1]: 右侧新增内容: { "id": "0002", "type": "donut", "name": "Raised", "ppu": 0.55, "batters": { "batter": [ { "id": "1001", "type": "Regular" } ] }, "topping": [ { "id": "5001", "type": "None" }, { "id": "5002", "type": "Glazed" }, { "id": "5005", "type": "Sugar" }, { "id": "5003", "type": "Chocolate" }, { "id": "5004", "type": "Maple" } ] } 路径root[2]: 右侧新增内容: { "id": "0003", "type": "donut", "name": "Old Fashioned", "ppu": 0.55, "batters": { "batter": [ { "id": "1001", "type": "Regular" }, { "id": "1002", "type": "Chocolate" } ] }, "topping": [ { "id": "5001", "type": "None" }, { "id": "5002", "type": "Glazed" }, { "id": "5003", "type": "Chocolate" }, { "id": "5004", "type": "Maple" } ] }
如果需要按行号列号展示差异,你可以把两个JSON文件先做统一缩进的美化格式化之后,用Python内置的difflib模块按行比对,即可得到行号维度的差异结果,匹配你示例里的输出格式。
内容的提问来源于stack exchange,提问作者CODSG
相关产品推荐
相关产品推荐

