增強json_tools模塊功能比對兩個json是否一樣
阿新 • • 發佈:2019-02-15
不一致 peer change 同步 fin pen [] nic 沒有
json_tools是python的一個第三方模塊,用於比對兩個目標json是否相等,如果相等則返回True,否則返回包含不相等項的list;
但是如果兩個目標json都中包含list,且兩個list原本是相同的,只是list中元素位置不一樣。這樣則json_tools是默認用兩個list中相同位置的元素進行比對,這樣原本一樣的list比對的結果是不相等的了。
如a=[a,b,c,d],b=[a,c,b,d],這兩個list本是一樣的,但是json_tools是用a==a,b==c,c==b,d==d進行對比,其結果自然是false;
我的算法是以a列表為模板,一個元素一個元素變量b列表,如果在b列表中發現一樣的元素,則將其調到與模板a列表中元素一樣的位置。如果沒有找到一樣的元素,則需要不一致元素最少的項(實際上list中的元素都是dict)
具體代碼如下:
#coding:utf-8
import json_tools,re
class JSONToolsExt(object):
#expectedvalue,response兩個進行對比的json
def isDiff(self,expectedvalue, response):
expdict=expectedvalue
respdict=response
result = json_tools.diff(expectedvalue, response) # 使用json_tools模塊的diff方法比較兩個json是否一致
other=None
if(result==True):
return True
elif(len(result)==0):
return True
else:
result_leng=len(result)
for i in range(result_leng):
keys=result[i].keys()
for key in keys:
if(key==‘replace‘):
v = re.findall("\d+", result[i].get(key))
if(v):
value_list=result[i].get(key)[1:].split(‘/‘)
for j in range(len(value_list)-1):
if(self.is_number(value_list[j])):
value_list=value_list[:j]
break
for k in range(len(value_list)):
expdict=expdict.get(value_list[k])
respdict=respdict.get(value_list[k])
templist=self.synchroJSONList(expdict,respdict) #expdict,respdict其實是list
other=self.changeList(value_list,response,templist)
result=json_tools.diff(expectedvalue, other)
break
if (result == True):
return True
elif (len(result) == 0):
return True
else:
result_i_keys=result[i].keys()
replace=None
v_b=[]
for key in result_i_keys:
if(key==‘replace‘):
replace=key
v_b = re.findall("\d+", result[i].get(replace))
break
if(replace==‘replace‘ and v_b):
break
return result
def synchroJSONList(self,explist=[],resplist=[]): #同步json中的list順序
templist=[]
for exp in explist:
leng=len(resplist)
for resp in resplist:
res=json_tools.diff(exp,resp)
if(res==True):
templist.append(resp)
resplist.remove(resp)
break
if(leng==len(resplist)):
likely=self.mostlikely(exp,resplist)
templist.append(likely)
resplist.remove(likely)
return templist
def mostlikely(self,exp,resplist): #尋找最可能的項
resp=resplist[0]
num=len(json_tools.diff(exp, resplist[0]))
for i in range(1,len(resplist)):
res = json_tools.diff(exp, resplist[i])
if(len(res)<num):
resp = resplist[i]
num=len(res)
return resp
def changeList(self,value_list,respdict,templist): #將新的列表替換老列表
n=0
r_bat=respdict
for i in range(len(value_list)-1):
r_bat=r_bat.get(value_list[i])
vs=value_list[len(value_list)-1]
r_bat[vs]=templist
return respdict
def is_number(self,s):
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
pass
return False
增強json_tools模塊功能比對兩個json是否一樣