• 增强json_tools模块功能比对两个json是否一样


    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列表中元素一样的位置。如果没有找到一样的元素,则寻找不一致元素最少的项(实际上json中list的元素都是dict)

    具体代码如下:
    #coding:utf-8
    import json_tools,re,unicodedata

    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): #如果一致则直接返回True
    return True
    elif(len(result)==0):
    return True
    else:
    result_leng=len(result)
    for i in range(result_leng):
    if(type(result[i])==type({})):
    keys=result[i].keys()
    for key in keys:
    if(key=='replace'):
    k_list=result[i].get(key).split('/')
    fv=False
    for k1 in k_list:
    v = self.is_number(k1)
    if(v):
    fv=True
    break
    if(fv):
    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])
    # if(type(expdict)==type([]) and type(respdict)==type([])):
    templist=self.synchroJSONList(expdict,respdict) #expdict,respdict其实是list
    other=self.changeList(value_list,response,templist)
    result=json_tools.diff(expectedvalue, other)
    break
    else:
    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=[]
    if(type(explist)==type([]) and len(explist)>0):
    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): #判断字符串s是否是数值
    try:
    float(s)
    return True
    except Exception as e:
    pass
    try:
    unicodedata.numeric(s)
    return True
    except Exception as e:
    pass
    return False
  • 相关阅读:
    redis内存模型、内存使用的优化
    【转】[Andriod]Xposed和VirtualXposed
    https详解
    http详解
    补码
    浮点数的二进制表示
    Go随机数
    ECDSA--圆锥曲线数字签名算法原理(摘wikepedia)
    Linux命令备忘
    【Windows】系统命令
  • 原文地址:https://www.cnblogs.com/shuyichao/p/10384186.html
Copyright © 2020-2023  润新知