一、deepdiff 库概述
在 Python 开发过程中,尤其是数据处理、接口测试、配置文件对比、数据同步校验等场景中,经常需要对比两个复杂数据结构(如字典、列表、集合、元组、自定义对象等)的差异。传统的对比方式仅能判断数据是否相等,无法精准定位差异位置、类型、具体内容,而 deepdiff 就是专门解决这一问题的第三方库。

deepdiff 核心作用是深度递归对比 Python 可哈希与不可哈希对象,精准找出两个对象之间的新增、删除、修改、值变化、类型变化、结构变化等差异,支持嵌套数据结构对比,无需手动编写递归遍历逻辑。其工作原理是通过递归遍历对象的每一层节点,逐一对比键、值、索引、数据类型,同时支持忽略指定字段、指定类型、指定路径等自定义规则。
该库优点是对比精度高、支持复杂嵌套结构、功能丰富、配置灵活,可满足绝大多数数据差异校验场景;缺点是对比超大规模数据时性能略有损耗,不适合极致性能要求的极简对比场景。deepdiff 采用 MIT License,开源免费,可商用、修改、分发,无严格版权限制。
二、deepdiff 安装方法
deepdiff 作为标准第三方库,可通过 pip 工具快速安装,支持 Python 3.6 及以上版本,安装命令如下:
pip install deepdiff若需要加速安装,可使用国内镜像源:
pip install deepdiff -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后,在 Python 脚本中直接导入即可使用,核心模块包括 DeepDiff、DeepSearch、grep、extract 等,满足不同对比与检索需求。
三、deepdiff 核心功能与基础使用
3.1 核心模块导入
deepdiff 最常用的核心类是 DeepDiff,用于深度对比两个对象,基础导入语句:
from deepdiff import DeepDiff除基础对比外,还可根据需求导入辅助模块:
# 深度搜索对象中的值
from deepdiff import DeepSearch
# 按规则检索数据
from deepdiff import grep
# 提取指定路径数据
from deepdiff import extract3.2 基础数据类型对比
deepdiff 支持数字、字符串、布尔值、None 等基础数据类型对比,直接传入两个待对比对象即可生成差异结果。
# 基础类型对比示例
from deepdiff import DeepDiff
# 定义两个待对比的基础数据
a = 100
b = 200
c = "python"
d = "Python"
e = True
f = False
# 数字对比
diff_num = DeepDiff(a, b)
print("数字差异结果:", diff_num)
# 字符串对比(区分大小写)
diff_str = DeepDiff(c, d)
print("字符串差异结果:", diff_str)
# 布尔值对比
diff_bool = DeepDiff(e, f)
print("布尔值差异结果:", diff_bool)代码说明:
- 直接传入两个基础类型变量,
DeepDiff自动判断是否相等; - 字符串对比默认区分大小写,数字、布尔值直接对比值;
- 结果会以字典形式返回,
values_changed表示值发生变化,包含新旧值与对比路径。
运行结果:
数字差异结果: {'values_changed': {'root': {'new_value': 200, 'old_value': 100}}}
字符串差异结果: {'values_changed': {'root': {'new_value': 'Python', 'old_value': 'python'}}}
布尔值差异结果: {'values_changed': {'root': {'new_value': False, 'old_value': True}}}3.3 列表数据对比
列表是开发中常用的数据结构,deepdiff 可对比列表的元素新增、删除、顺序变化、值变化,支持嵌套列表对比。
# 列表对比示例
from deepdiff import DeepDiff
# 普通列表对比
list1 = [1, 2, 3, 4]
list2 = [1, 2, 5, 4, 6]
diff_list = DeepDiff(list1, list2)
print("普通列表差异:", diff_list)
# 嵌套列表对比
nested_list1 = [1, [2, 3], 4]
nested_list2 = [1, [2, 5], 4, 7]
diff_nested_list = DeepDiff(nested_list1, nested_list2)
print("嵌套列表差异:", diff_nested_list)代码说明:
iterable_item_added表示列表新增元素;iterable_item_removed表示列表删除元素;- 嵌套列表会递归遍历每一层子列表,精准定位子元素变化。
运行结果:
普通列表差异: {'iterable_item_added': {'root[4]': 6}, 'values_changed': {'root[2]': {'new_value': 5, 'old_value': 3}}}
嵌套列表差异: {'iterable_item_added': {'root[3]': 7}, 'values_changed': {'root[1][1]': {'new_value': 5, 'old_value': 3}}}3.4 字典数据对比
字典是配置文件、接口返回数据的常用结构,deepdiff 可对比字典的键新增、键删除、键值修改、嵌套字典变化,是接口自动化测试、配置文件校验的核心用法。
# 字典对比示例
from deepdiff import DeepDiff
# 普通字典对比
dict1 = {"name": "张三", "age": 20, "gender": "男"}
dict2 = {"name": "张三", "age": 21, "city": "北京"}
diff_dict = DeepDiff(dict1, dict2)
print("普通字典差异:", diff_dict)
# 嵌套字典对比
nested_dict1 = {"user": {"name": "李四", "info": {"score": 90}}, "status": True}
nested_dict2 = {"user": {"name": "李四", "info": {"score": 95}}, "status": False}
diff_nested_dict = DeepDiff(nested_dict1, nested_dict2)
print("嵌套字典差异:", diff_nested_dict)代码说明:
dictionary_item_added:字典新增键值对;dictionary_item_removed:字典删除键值对;values_changed:字典键对应的值发生变化;- 嵌套字典会递归解析每一层子字典,路径清晰便于定位问题。
运行结果:
普通字典差异: {'dictionary_item_added': {'root['city']': '北京'}, 'dictionary_item_removed': {'root['gender']': '男'}, 'values_changed': {"root['age']": {'new_value': 21, 'old_value': 20}}}
嵌套字典差异: {'values_changed': {"root[0]['user']['info']['score']": {'new_value': 95, 'old_value': 90}, "root['status']": {'new_value': False, 'old_value': True}}}3.5 集合与元组对比
deepdiff 同样支持集合、元组的对比,集合对比自动忽略顺序,仅判断元素增减;元组对比兼顾顺序与值变化。
# 集合与元组对比
from deepdiff import DeepDiff
# 集合对比
set1 = {1, 2, 3}
set2 = {2, 3, 4}
diff_set = DeepDiff(set1, set2)
print("集合差异:", diff_set)
# 元组对比
tuple1 = (1, 2, 3)
tuple2 = (1, 4, 3)
diff_tuple = DeepDiff(tuple1, tuple2)
print("元组差异:", diff_tuple)代码说明:
- 集合对比结果为
set_item_added和set_item_removed; - 元组属于有序不可变对象,对比逻辑与列表一致。
四、deepdiff 高级配置与实用参数
deepdiff 提供丰富的配置参数,可自定义对比规则,满足复杂场景需求,以下是最常用的高级参数。
4.1 忽略指定字段对比
在接口测试或配置对比中,经常需要忽略时间戳、随机ID、日志字段等,使用 exclude_paths 参数实现。
# 忽略指定字段对比
from deepdiff import DeepDiff
data1 = {
"id": 1001,
"name": "产品A",
"time": "2025-01-01 12:00:00",
"price": 99
}
data2 = {
"id": 1001,
"name": "产品A",
"time": "2025-01-02 12:00:00",
"price": 99
}
# 忽略 time 字段
diff = DeepDiff(data1, data2, exclude_paths=["root['time']"])
print("忽略time字段后的差异:", diff)代码说明:exclude_paths 接收列表参数,传入需要忽略的字段路径,对比时自动跳过该字段,结果中无相关差异。
4.2 忽略数据类型变化
部分场景中,数字与字符串形式的相同值(如 100 和 “100”)视为相等,使用 ignore_type_in_groups 参数。
# 忽略类型变化
from deepdiff import DeepDiff
obj1 = {"num": 100}
obj2 = {"num": "100"}
# 忽略 int 和 str 类型差异
diff = DeepDiff(obj1, obj2, ignore_type_in_groups=[(int, str)])
print("忽略类型变化后的结果:", diff)代码说明:ignore_type_in_groups 可指定多组类型组合,对比时相同值不同类型会被判定为无差异。
4.3 忽略字符串大小写与空格
对比字符串时,可忽略大小写、首尾空格、中间多余空格,提升对比容错率。
# 忽略字符串大小写与空格
from deepdiff import DeepDiff
str_obj1 = {"content": " Python DeepDiff "}
str_obj2 = {"content": "python deepdiff"}
# 忽略大小写、首尾空格
diff = DeepDiff(str_obj1, str_obj2, ignore_string_case=True, ignore_string_whitespace=True)
print("忽略字符串格式后的结果:", diff)4.4 精确对比与数学近似对比
对比浮点数时,避免精度误差导致误判,可设置 number_accuracy 参数指定精度范围。
# 浮点数近似对比
from deepdiff import DeepDiff
num1 = {"value": 3.14159}
num2 = {"value": 3.1416}
# 保留4位小数对比
diff = DeepDiff(num1, num2, number_accuracy=4)
print("浮点数精度对比结果:", diff)五、DeepSearch 深度搜索功能
DeepSearch 可在复杂嵌套数据中,搜索指定值、键、类型,返回匹配路径,是数据检索的实用功能。
# DeepSearch 深度搜索示例
from deepdiff import DeepSearch
data = {
"class": "一年级",
"students": [
{"name": "小明", "score": 90},
{"name": "小红", "score": 95},
{"name": "小刚", "score": 90}
]
}
# 搜索值为90的所有路径
search = DeepSearch(data, 90)
print("值为90的匹配路径:", search)代码说明:
DeepSearch 会遍历整个数据结构,返回所有匹配目标值的节点路径,方便快速定位数据位置。
六、实际开发场景综合案例
6.1 接口自动化测试数据对比
接口测试中,需要校验接口返回数据与预期数据是否一致,deepdiff 可快速定位返回值异常。
# 接口测试数据对比案例
from deepdiff import DeepDiff
# 预期返回数据
expect_data = {
"code": 200,
"msg": "success",
"data": {
"user_id": 123,
"username": "test_user",
"role": "user"
}
}
# 实际返回数据
actual_data = {
"code": 200,
"msg": "success",
"data": {
"user_id": 123,
"username": "test_user",
"role": "admin"
}
}
# 对比接口数据,忽略无意义字段
diff_result = DeepDiff(expect_data, actual_data, exclude_paths=["root['msg']"])
print("接口数据差异:", diff_result)
# 判断是否存在差异
if diff_result:
print("接口返回数据异常!")
else:
print("接口返回数据正常!")代码说明:
该案例模拟接口测试场景,通过对比预期与实际数据,快速发现角色字段异常,提升测试效率。
6.2 配置文件前后版本对比
项目配置文件修改后,可使用 deepdiff 对比新旧配置,避免误改导致项目异常。
# 配置文件对比案例
from deepdiff import DeepDiff
# 旧版本配置
old_config = {
"debug": False,
"port": 8080,
"database": {
"host": "127.0.0.1",
"port": 3306,
"db": "test"
}
}
# 新版本配置
new_config = {
"debug": True,
"port": 8090,
"database": {
"host": "127.0.0.1",
"port": 3306,
"db": "prod"
}
}
# 完整对比配置差异
config_diff = DeepDiff(old_config, new_config)
print("配置文件版本差异:", config_diff)6.3 数据同步前后校验
数据同步、数据迁移场景中,使用 deepdiff 校验源数据与目标数据是否完全一致,确保数据无丢失、无篡改。
# 数据同步校验案例
from deepdiff import DeepDiff
# 源数据
source_data = [
{"id": 1, "name": "苹果", "stock": 100},
{"id": 2, "name": "香蕉", "stock": 200}
]
# 同步后目标数据
target_data = [
{"id": 1, "name": "苹果", "stock": 100},
{"id": 2, "name": "香蕉", "stock": 250}
]
# 校验同步结果
sync_diff = DeepDiff(source_data, target_data)
print("数据同步差异:", sync_diff)七、相关资源
- Pypi地址:https://pypi.org/project/deepdiff/
- Github地址:https://github.com/seperman/deepdiff
- 官方文档地址:https://zepworks.com/deepdiff/current/
关注我,每天分享一个实用的Python自动化工具。

