Python實現json串比對並輸出差異結果
阿新 • • 發佈:2022-03-02
#!/usr/bin/env python # -*- coding: UTF-8 -*- """ @Descrip : @Project :tools @File :test.py @Author :guolihai @Date :2022/03/02 15:04 """ import json class JsonCompare: def __init__(self, second_data, first_data, debug_model=False): """ :param second_data: :param first_data: :param debug_model:""" self.compare_result = [] # 存放欄位差異 self.compare_error = [] # 存放欄位比對異常 self.compare(second_data, first_data) if debug_model: for i in self.compare_result: print('-----:{}'.format(i)) for i in self.compare_error:print(i) def result(self): # s = "".join(self.compare_result) return self.compare_result def compare(self, second_data, first_data, path=''): try: if not isinstance(second_data, (list, tuple, dict)): # 比對非list\tuple\dict型別的資料 ifnot second_data == first_data: msg = { # 'field': path, 'field': "差異位置=>" + path, # 'error_type': 'field value diff', 'error_type': '欄位的值不同', 'secondResp': second_data, 'firstResp': first_data } self.compare_result.append(msg) elif isinstance(second_data, (list, tuple)): # 如果新資料是list/tuple,則判斷老資料是否型別一致;不一致則追加到compare_error if type(second_data) != type(first_data): msg = { # 'field': path, '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) return if len(second_data) != len(first_data): msg = { # 'field': path, '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, '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) return new_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}", 'field': "差異位置=>" + f"{path}:{key}", # 'error_type': 'field missing', 'error_type': '欄位缺少', 'secondResp': value, # 'firstResp': f"Field of '{key}' is not exists" 'firstResp': f"欄位 '{key}' 不存在" } 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}", 'field': "差異位置=>" + f"{path}:{key}", # 'error_type': 'field missing', 'error_type': '欄位缺少', # 'secondResp': f"Field of '{key}' is not exists", 'secondResp': f"欄位 '{key}' 不存在", 'firstResp': first_data[key] } self.compare_result.append(msg) except Exception as e: self.compare_error.append( f'Unknown error:{e.args}') if __name__ == '__main__': a = {"pid": "2101051131450820a0122893623", "sign": "d7c7a8c117a2a209bf096e0eeab8b21f", "data": {"trainDate": "2022-03-13 00:00:00", "fromStation": [{"xx": "ss"}, {"tt": ""}], "toStation": "成都"}, "pGroupId": "2105081114363770a0175031531"} b = {"pid": "2101051131450820a0122893623", "timestamp": 1646189746138, "sign": "d7c7a8c117a2a209bf096e0eeab8b21f", "data": {"trainDate": "2022-03-13 00:00:00", "fromStation": [{"xx": "ss"}, {"tt": "55655"}], "toStation": "ff"}, "pp": "2105081114363770a0175031531"} x = JsonCompare(b, a, debug_model=False).result() print(json.dumps(x, ensure_ascii=False)) # print(x) for i in x: print(i)
執行結果: