json自定义格式内容对比工具

需求背景:

风控决策引擎的需求树和配置界面比对,由于树比较“粗壮”,人工比对工作量实在太大,由于树是有json绘制而成,故可以将树的json与配置界面的结果——数据库中的json做比对,提升工作效率。

  • part 1 :json文件导入
1
2
3
import json
d1 = json.load(open('/文件目录/json1.json'))
d2 = json.load(open('/文件目录/json2.json'))
  • part 2 : 修改自定义规则部分
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
  • part 4 处理dict中嵌套list的情况
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)
  • part 5 :异常处理及测试
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)