Python修改嵌套字典的key值

  最近在搞接口测试的时候发现了一个比较有趣的json入参数,结构如下:

json = {"aa": "33", "bb": [{"gg": "33"}, {"jj": [{"gg": "33"}, {"haha": [{"gg": "33"}, {"yyyu": [{"yy": "希望调试成功", "kk": {"uu": "hr", "lll": {"gg": "33"}}}]}]}]}], "gg": "33"}

观察该json数据,我们发现有大量的相同的key(gg),并且这些key的value值都是一样的,那么我们需要修改所有key(gg)的值,应该怎么做呢?


 

提问:为什么会有这么有趣的入参数据?

我也不知道,因为公司的出库单的业务数据就有这么可怕和奇葩的数据,只是没有本文中举例的那么夸张

  第一:我们可以把这个数据封装成一个函数,实现如下所示:

def data(gg):
    dict_data = {'aa': '33', 'bb': [{'gg': gg}, {'jj': [{'gg': gg}, {
        'haha': [{'gg': gg}, {'yyyu': [{'yy': '希望调试成功', 'kk': {'uu': 'hr', 'lll': {'gg': gg}}}]}]}]}], 'gg': gg}
    return dict_data

print(data('hahaha'))

这样很完美的解决我们的问题了。完美,解题结束......enenen、但是这会引生出另一个问题,就是每次接口改动需要去修改代码,不便于工具化(虽然在接口自动化后接口不太可能会发生改动),

对于测试来说不可能人人都去搞工具化,但是你不能没有一个工具化的心。

  OK,目标明确了,那么我们需要搞个好的思路了,但是在这之前我们不得不先了解一下python对于字典的操作:

  首先,最简单的方法是直接创建字典dict={"name":"张三","age":"23"}

  再次,先创建一个空字典,然后对字典进行赋值或者修改,具体如下图所示:

 

 从上图中可以看出,我们是可以直接对字典进行操作的结构为dict["key"] = value,dict["key"] 表示字典的key,value表示key的值,简单点说就是字典里面的元素,

以及元素的值是什么,但是有一点要清楚,字典里面key的值它可以是一个字符串,可以是数字,可以是列表,可以是字典。(说明:在python中json串可以理解是一个字典)。

不难理解,我们在上图中直接对一个空字典定义了元素和元素值,那么对嵌套字典改如何进行操作呢?这里以比较有趣的json入参数进行讲解:

 

 

 如上图所示,每一个需要修改的key都需要指明路径,所以非常麻烦,非常难搞,随着明细的增加,说不定形同名称的key还会更多,然后有需要手动指明,

这种方法还不如用函数去修改key的值,所以还需要再想想办法。

想不到更多的表达语言,直接看如下代码:

dict_data = {'aa': '33', 'bb': [{'gg': ''}, {'jj': [{'gg': 'gg'}, {
        'haha': [{'gg': 'gg'}, {'yyyu': [{'yy': '希望调试成功', 'kk': {'uu': 'hr', 'lll': {'gg': 'gg'}}}]}]}]}], 'gg': 'gg'}

key = 'gg'


def update(key,dict_data):
    #判断需要修改的key是否在初始字典中,在则修改
    if key in dict_data:
        #将key为'gg'的值修改成'张三'
        dict_data[key]='张三'
        #print(dict_data)
        #循环字典获取到所有的key值和value值
        for keys,values in dict_data.items():
            #判断valus值是否为列表或者元祖
            if isinstance(values,(list,tuple)):
                #循环获取列表中的值
                for i in values:
                    #判断需要修改的值是否在上一个循环出的结果中,在则修改
                    if key in i and isinstance(i,dict):
                        #调用自身修改函数,将key的值修改成'张三'
                        update(key,i)
                    else:
                        #否者则调用获取value函数
                        get_value(i)
            elif isinstance(values,dict):
                if key in values:
                    update(key,values)
                else:
                    for keys,values in values.items():
                        if isinstance(values,dict):
                            update(key, values)
    else:
        #循环获取原始字典的values值
        for keys,values in dict_data.items():
            #判断values值是否是列表或者元祖
            if isinstance(values,(list,tuple)):
                #如果是列表或者元祖则循环获取里面的元素值
                for i in values:
                    #判断需要修改的key是否在元素中
                    if key in i:
                        #调用修改函数修改key的值
                        update(key,i)
                    else:
                        #否则调用获取values的值函数
                        get_value(i)
            #判断values值是否为字典
            elif isinstance(values,dict):
                #判断需要修改的key是否在values中
                if key in values:
                    #调用修改函数修改key的值
                    update(key,values)
                else:
                    #获取values值的函数
                    get_value(values)
    return dict_data


def get_value(tt):
    #循环获取values的值
    for values in tt.values():
        #判断循环出的value的值是否为列表或者元祖
        if isinstance(values, (list,tuple)):
            #如果为列表或者元祖则循环获取列表或者元祖中的值
            for i in values:
                #判断需要修改的值是否在循环出的值中,且i为字典
                if key in i and isinstance(i,dict):
                    #调用修改函数,将key的值修改为'张三'
                    update(key, i)
                else:
                    #否则调用获取value函数
                    get_value(i)
        elif isinstance(values,dict):
            if key in values:
                update(key, values)
            else:
                get_value(values)

update(key,dict_data)

如上图代码所示:总的来说就是将字典循环判断曲直并修改,然后就完事了咯。

这样做的好处是,我们在做接口自动化的时候可以将数据与脚本分离,只需在excel中维护好入参,指定获取返回变量值即可

 

posted @ 2021-04-01 15:58  雪山狼  阅读(3035)  评论(0编辑  收藏  举报