You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归比对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:36:07