主要是利用递归,逐层级、逐次、逐字段比较;可以用于幂等类接口的返回体校验。

class JsonCompare:def __init__(self, second_data, first_data, debug_model=False):"""用于两个json串比对,输出两串json字段差异:param second_data: 用于比对的新json:param first_data: 基准json:param debug_model: 为True时将在控制台输出比对结果,默认不开启"""self.compare_result = []  # 存放字段差异self.compare_error = []  # 存放字段比对异常self.compare(second_data, first_data)if debug_model:for i in self.compare_result:print(i)for i in self.compare_error:print(i)def compare(self, second_data, first_data, path=''):try:if not isinstance(second_data, (list, tuple, dict)):# 比对非list\tuple\dict类型的数据if not second_data == first_data:msg = {'field': path,'error_type': 'field value diff','secondResp': second_data,'firstResp': first_data}self.compare_result.append(msg)elif isinstance(second_data, (list, tuple)):# 如果新数据是list/tuple,则判断老数据是否类型一致;不一致则追加到compare_errorif type(second_data) != type(first_data):msg = {'field': path,'error_type': "field type diff",'secondResp': f"type is {type(second_data)}",'firstResp': f"type is {type(first_data)}"}self.compare_result.append(msg)returnif len(second_data) != len(first_data):msg = {'field': path,'error_type': "field indexLength diff",'secondResp': f"Length of list is {len(second_data)}",'firstResp': f"Length of list is {len(first_data)}"}self.compare_result.append(msg)for index, value in enumerate(second_data):try:if index < len(first_data):self.compare(value, first_data[index], f'{path}:{index}')else:self.compare(value, {}, f'{path}:{index}')except Exception as e:self.compare_error.append(f'Unknown error: {e.args}')else:# 比对值为dict类型数据if not isinstance(first_data, dict):msg = {'field': path,'error_type': "field type diff",'secondResp': f"type is {type(second_data)}",'firstResp': f"type is {type(first_data)}"}self.compare_result.append(msg)returnnew_keys = set(second_data.keys())old_keys = set(first_data.keys())diff_keys = old_keys - new_keys  # 用于检查老数据存在某个key,但新数据不存在。for key, value in second_data.items():try:if key in first_data.keys():self.compare(value, first_data[key], f"{path}:{key}")else:msg = {'field': f"{path}:{key}",'error_type': 'field missing','secondResp': value,'firstResp': f"Field of '{key}' is not exists"}self.compare_result.append(msg)except Exception as e:self.compare_error.append(f'Unknown error:{e.args}')if diff_keys:for key in diff_keys:msg = {'field': f"{path}:{key}",'error_type': 'field missing','secondResp': f"Field of '{key}' is not exists",'firstResp': first_data[key]}self.compare_result.append(msg)except Exception as e:self.compare_error.append(f'Unknown error:{e.args}')

使用方法:

_old_data = {"key1": "value1","key2": "value2","key3": [1],"object": {"object_key1": "object_value2","object_key2": {"sub_key": "object_key2_sub_value"},"object_key3": [{"list_sub_key1": "xx"},{"list_sub_key2": "xx"}]},"x": 1.2}
_new_data = {"key1": "value1","key2": "value2","key3": (1,),"object": {"object_key1": "object_value1","object_key2": {"sub_key": "object_key2_sub_value","sub_key2": {"xx": 1}},"object_key3": [{"list_sub_key1": "xx"},{"list_sub_key2": []}]},"x": 1.2
}print("方式一:")
JsonCompare(_new_data, _old_data, debug_model=True)
print("方式二:")
json_compare = JsonCompare(_new_data, _old_data)
print(json_compare.compare_result)
print(json_compare.compare_error)
=======================================================================
方式一:
{'field': ':key3', 'error_type': 'field type diff', 'secondResp': "type is <class 'tuple'>", 'firstResp': "type is <class 'list'>"}
{'field': ':object:object_key1', 'error_type': 'field value diff', 'secondResp': 'object_value1', 'firstResp': 'object_value2'}
{'field': ':object:object_key2:sub_key2', 'error_type': 'field missing', 'secondResp': {'xx': 1}, 'firstResp': "Field of 'sub_key2' is not exists"}
{'field': ':object:object_key3:1:list_sub_key2', 'error_type': 'field type diff', 'secondResp': "type is <class 'list'>", 'firstResp': "type is <class 'str'>"}
方式二:
[{'field': ':key3', 'error_type': 'field type diff', 'secondResp': "type is <class 'tuple'>", 'firstResp': "type is <class 'list'>"}, {'field': ':object:object_key1', 'error_type': 'field value diff', 'secondResp': 'object_value1', 'firstResp': 'object_value2'}, {'field': ':object:object_key2:sub_key2', 'error_type': 'field missing', 'secondResp': {'xx': 1}, 'firstResp': "Field of 'sub_key2' is not exists"}, {'field': ':object:object_key3:1:list_sub_key2', 'error_type': 'field type diff', 'secondResp': "type is <class 'list'>", 'firstResp': "type is <class 'str'>"}]
[]

Python实现json串比对并输出差异结果相关推荐

  1. python post 请求json文件_requests的post请求提交表单、json串和文件数据讲解

    HTTP协议中没有规定post提交的数据必须使用什么编码方式,服务端根据请求头中的Content-Type字段来获取编码方式,再对数据进行解析.具体的编码方式包括如下: - application/x ...

  2. Python中读取文件中的json串,并将其写入到Excel表格中

    Json:JavaScript Objective Notation,是一种轻量级的数据交换格式.Json最广泛的应用是作为AJAX中web服务器和客户端的通讯的数据格式.现在也常用语http请求中, ...

  3. Python: Json串反序列化为自定义类对象

    最近刚接触到python,就想到了如何反序列化json串.网上找了一下,大部分都是用json模块反序列化为python数据结构(字典和列表).如果对json模块不了解的参考菜鸟教程.然后我在此基础上将 ...

  4. pythonの鉴黄之路(五)——强行解析json串

    *以下内容并非正规解决方案,效仿请谨慎. 之前有介绍过阿里云的鉴黄API接口http://blog.csdn.net/sm9sun/article/details/53321888 其支持:porn: ...

  5. Python: 自定义类对象序列化为Json串

    之前已经实现了Python: Json串反序列化为自定义类对象,这次来实现了Json的序列化. 测试代码和结果如下: import Json.JsonToolclass Score:math = 0c ...

  6. (三)Python反爬实战---JS反爬之某网站将json串Data数据加密成一串数字字母

       python反爬经验实战,适合小白入门,新手提升,大牛晋升.包含本人目前遇到反爬汇总,文章一周2-3篇,为了质量考虑,更新较慢,敬请谅解.购买专栏私信博主加微信,可无偿提供学习辅助. 考虑到新手 ...

  7. python的json格式输出_python中json格式数据输出实现方式

    python中json格式数据输出实现方式 主要使用json模块,直接导入import json即可. 小例子如下: #coding=UTF-8 import json info={} info[&q ...

  8. python读取中文文件乱码-详解Python的json文件读取及中文乱码显示问题解决方法...

    Python的json文件读取及解决中文乱码显示问题 本文实例讲述了Python实现的json文件读取及中文乱码显示问题解决方法.分享给大家供大家参考,具体如下: city.json文件的内容如下: ...

  9. python操作json字符串,超详细的Python文件操作知识

    来自:CSDN,作者:南枝向暖北枝寒MA 链接:https://blog.csdn.net/mall_lucy/article/details/104547365 [导语]:python进行文件操作, ...

最新文章

  1. 由各大企业移除MongoDB,回看关系模型与文档模型之争
  2. Spring MVC拦截器+注解方式实现防止表单重复提交
  3. 记一次 webpack 打包体积优化
  4. PHP开发中csrf攻击的简单演示和防范
  5. Bootstrap css3
  6. robot:截图关键字
  7. 论文浅尝 | Data Intelligence 已出版的知识图谱主题论文
  8. vi(vim)编辑器 学习笔记
  9. 实现 npm script 跨平台兼容
  10. POJ 1986:Distance Queries(倍增求LCA)
  11. vue cli脚手架详解_vue-cli脚手架搭建vue项目搭建
  12. 房产估值软件测试怎么报风险,基于风险的测试策略
  13. 强大的DataGrid组件[4]_实现CURD[上]——Silverlight学习笔记[12]
  14. Tricks(三十七)—— C++ string类 split 的实现
  15. UVa 10003 Cutting Sticks(区间DP)
  16. java8 64位安装_Java8安装步骤-win10-64位系统
  17. linux环境下pandas库的安装,Pandas库的基本使用 pip安装 Series DataFrame
  18. word表格中多行只有一行字,让一行字居中的设置操作
  19. 企业信息安全————3、如何建立企业安全框架
  20. java jsp使用flash播放mp4,(jsp/html)网页上嵌入播放器(常用播放器代码整理)

热门文章

  1. MATLAB/Simulink 线性分析工具箱频域分析(手把手教会)
  2. Lifecycle 使用与源码分析
  3. Spine动画显示错乱问题
  4. 华润置地php面试题_华润置地有限公司面试攻略,面试题,面试技巧及流程(附笔试,评论,薪资)-金针菇企评网...
  5. 安卓虚拟键盘_逍遥安卓模拟器对电脑配置有什么要求
  6. 为什么网上Python爬虫教程这么多,但是做爬虫的这么少呢?爬虫发展又该是如何呢?
  7. 一站式在线医疗解决方案,即构音视频技术助建互联网医疗
  8. Fluent中的压力类型
  9. 一个人靠不靠谱,就看这三件小事
  10. c语言怎么实现plc的自锁功能,【图】plc梯形图自锁与互锁功能编程实例