需求背景:
风控决策引擎的需求树和配置界面比对,由于树比较“粗壮”,人工比对工作量实在太大,由于树是有json绘制而成,故可以将树的json与配置界面的结果——数据库中的json做比对,提升工作效率。
1 2 3
| import json d1 = json.load(open('/文件目录/json1.json')) d2 = json.load(open('/文件目录/json2.json'))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #遍历json,将两个json中对应的key,但命名不一致部分修改为相同的;将value格式不同的修改为相同的 def cmp_dict(a,b): if isinstance(a,dict): for key,value in a.items(): keyb = key if key == 'code': a[key] = a[key].replace('_','.') value = value.replace('_','.') keyb = '_name' if key == 'condition': keyb = 'conditions' if key == 'math': keyb = 'ruleFusion' for case in switch(a[key]): if case('VECTORNORM(2)'): a[key] = 'rfmNorm2' break 。 。 。 if case(): # 默认 print "something else!" #将json中多个值组装后,再匹配 的逻辑较多,不展示了 #最后,加个递归调用 cmp_dict(a[key],b[keyb])
|
- part 3 :由于上面switch部分较多,为了避免写太多if…else导致可读性太差,编写了一个switch类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class switch(object): def __init__(self, value): self.value = value self.fall = False def __iter__(self): """Return the match method once, then stop""" yield self.match raise StopIteration def match(self, *args): """Indicate whether or not to enter a case suite""" if self.fall or not args: return True elif self.value in args: # changed for v1.5, see below self.fall = True return True else: return False
|
1 2 3 4 5 6
| elif isinstance(a,list): #sorted方法为python中list的排序方法;zip方法将两个list中对应的数据打包成元组 for src_list, dst_list in zip(sorted(a, key=lambda x : (x.get('level', 0))),sorted(b, key=lambda x : (x.get('level', 0)))): #将json中多个值组装后,再匹配 的逻辑较多,不展示了 #最后,加个递归调用 cmp_dict(src_list, dst_list)
|
1 2 3 4 5 6 7 8
| try ... except: f=open("/文件目录/log.txt",'a') traceback.print_exc(file=f) f.flush() f.close()
|
1 2 3 4 5
| if __name__ == "__main__": xx = {"111":None,"23456":{"22222":9999,"33333":"0000","list":["3333","4444","111"]}} yy = {"111":None,"23456":{"22222":9999,"33333":"0000","list":["111","3333","4444"]}} mp_dict(x,y) cmp_dict(d1,d2)
|