本工具可以嵌套比较2个json结构是否相同,以及值是否相等,记录了详细的对比差异。
# -*- coding: UTF-8 -*-"""@file:jsonCompareUtil.py@time:/06/17"""class JsonCompareUtil:@classmethoddef compareValues(cls, source, target, compare_result:list, *ignores, path='')->list:"""递归对比两个json串的value,返回具体的对比说明:param source: 比较的模板json:param target: 目标json:param ignores: 忽略对比的key:param path: 不用传:param compare_result: 存放对比结果, 必须是list"""if not isinstance(compare_result, list):raise TypeError('pareValues方法的result参数类型不是list')if not isinstance(source, (list, tuple, dict, set)):# 比对非list、tuple、dict、set类型的数据if not source == target:msg = {'field': path,'error_type': '值不相等','source': source,'target': target}compare_result.append(msg)elif isinstance(source, (list, tuple, set)):#类型是否一致if type(source) != type(target):msg = {'field': path,'error_type': "类型不一致",'source': f"类型={type(source)}",'target': f"类型={type(target)}"}compare_result.append(msg)return#长度是否一致if len(source) != len(target):msg = {'field': path,'error_type': "数组长度不一致",'source': f"数组长度={len(source)}",'target': f"数组长度={len(target)}"}compare_result.append(msg)return#值是否一致for index, value in enumerate(source):if index < len(target):pareValues(value, target[index], compare_result, *ignores, path = f'{path}[{index}]' if path else f'{index}')else:pareValues(value, {}, compare_result, *ignores, path = f'{path}[{index}]' if path else f'{index}')else:#比对值为dict类型数据if not isinstance(target, dict):msg = {'field': path,'error_type': "目标非dict",'source': f"源类型={type(source)}",'target': f"目标类型={type(target)}"}compare_result.append(msg)returnsource_keys = source.keys()target_keys = target.keys()#求差集diff_keys = list(source_keys ^ target_keys)#有key不同if diff_keys:for key in diff_keys:msg = {'field': f"{path}.{key}" if path else f'{key}','error_type': '字段缺失','source': source.get(key, None),'target': target.get(key, None)}compare_result.append(msg)#key都相同,递归处理else:for key, value in source.items():if key in ignores:continueif key in target.keys():pareValues(value, target[key], compare_result, *ignores, path = f"{path}.{key}" if path else f'{key}')else:msg = {'field': f"{path}.{key}" if path else f'{key}','error_type': '字段缺失','source': value,'target': f"字段[{key}]缺失"}compare_result.append(msg)@classmethoddef compareKeys(cls, source, target, compare_result:list, path=''):"""递归对比两个json的结构,返回具体的对比说明:param source: 比较的模板json:param target: 目标json:param path: 不用传:param compare_result: 存放对比结果, 必须是list"""if not isinstance(compare_result, list):raise TypeError('pareValues方法的result参数类型不是list')#数组if isinstance(source, list) and isinstance(target, list):#递归处理里面的dictfor a, b in zip(source, target):pareKeys(a, b, compare_result, path=path)if isinstance(source, dict) and isinstance(target, dict):source_keys = source.keys()target_keys = target.keys()#求差集diff_keys = list(source_keys ^ target_keys)#有key不同if diff_keys:for key in diff_keys:msg = {'field': f"{path}.{key}" if path else f'{key}','error_type': '字段缺失','source': source.get(key, None),'target': target.get(key, None)}compare_result.append(msg)#key都相同,递归处理else:for key, value in source.items():#字典嵌套if isinstance(value, dict):pareKeys(value, target.get(key), compare_result, path=f'{path}.{key}' if path else key)#列表中包含字典elif isinstance(value, list):pareKeys(value, target.get(key), compare_result, path=f'{key}[*]')if __name__ == '__main__':source1 = {"returnStatus": "SUCCEED","serverTime": "1655429850722","requestId": "6fe938f38bec47ac89ef92fed90ef306","data": {"switch": {"key1":1},"params": {"retryDelay": 60}}}target1 = {"returnStatus": "SUCCEED","serverTime": "1655429850722","requestId": "6fe938f38bec47ac89ef92fed90ef306","data": {"params": {"retryDelay": 80}}}result = []pareValues(source1, target1, result)print(result)source2 = {"returnStatus": "SUCCEED","serverTime": "1655429850722","requestId": "6fe938f38bec47ac89ef92fed90ef306","data": {"params": {"retryDelay": 60}}}target2 = {"returnStatus": "SUCCEED","serverTime": "1655429850722","requestId": "6fe938f38bec47ac89ef92fed90ef306","data": {"params": {"retryDelay": 60,"maxStoredSize": 200,"daySizeMax": 50000,"retryTime": 3,"packageSize": 80}}}result = []pareValues(source2, target2, result)print(result)
如果觉得《json结构 值对比python源码实现》对你有帮助,请点赞、收藏,并留下你的观点哦!