如何用Python Pydantic模型校验对比两个乱序嵌套JSON?
实现方案
完全可以通过Pydantic实现乱序嵌套JSON的匹配校验,具体实现如下:
第一步:安装依赖
推荐使用Pydantic V2版本,执行安装命令:pip install pydantic
第二步:定义嵌套Pydantic模型
根据你给出的JSON结构定义对应的模型,同时自定义忽略列表顺序的对比方法:
from pydantic import BaseModel from typing import List # 定义各层级对应模型 class ColumnItem(BaseModel): name2: str nameid: str class DemoItem(BaseModel): name1: str surname: str columns: List[ColumnItem] class AbxItem(BaseModel): name: str colors: str demo: List[DemoItem] class ApiResponse(BaseModel): abx: List[AbxItem] # 自定义忽略列表顺序的对比方法 def equals_ignore_order(self, other: "ApiResponse") -> bool: # 按各层级唯一标识排序,没有固定唯一键的话也可以把子模型转成json字符串作为排序key sort_keys = { "abx": lambda x: x.name, "demo": lambda x: x.name1, "columns": lambda x: x.nameid } # 递归排序当前对象所有嵌套列表 def sort_nested(obj): if isinstance(obj, list): if obj and hasattr(obj[0], "name"): return sorted([sort_nested(item) for item in obj], key=sort_keys["abx"]) elif obj and hasattr(obj[0], "name1"): return sorted([sort_nested(item) for item in obj], key=sort_keys["demo"]) elif obj and hasattr(obj[0], "name2"): return sorted([sort_nested(item) for item in obj], key=sort_keys["columns"]) return obj elif isinstance(obj, BaseModel): for field in obj.model_fields: setattr(obj, field, sort_nested(getattr(obj, field))) return obj return obj sorted_self = sort_nested(self.model_copy(deep=True)) sorted_other = sort_nested(other.model_copy(deep=True)) return sorted_self == sorted_other
第三步:对比两个响应
# 假设resp_json1、resp_json2是你拿到的两个响应字典 # 先做结构校验,结构不符合要求会直接抛出ValidationError model1 = ApiResponse(**resp_json1) model2 = ApiResponse(**resp_json2) # 执行忽略顺序的内容对比 if model1.equals_ignore_order(model2): print("两个响应内容完全匹配") else: print("两个响应存在差异")
补充说明
- 如果需要输出具体的差异字段,可以结合
deepdiff库使用,将两个排序后的模型转成字典后传入DeepDiff方法即可得到详细差异 - 如果你使用的是Pydantic V1版本,只需要将代码中
model_fields替换为__fields__、model_copy替换为copy即可,核心逻辑完全通用
内容的提问来源于stack exchange,提问作者learning
相关产品推荐
相关产品推荐

