接口测试 python 分享一个通过 (key1.key2.key3) 形式获取嵌套字典值的方法

重拾 · March 21, 2017 · Last by Zero.S replied at December 18, 2018 · 7484 hits

最近在做接口自动化测试,响应的内容大多数是多层嵌套的json数据,如果一层层的去剥,效率不高,脚本繁重,所以写了一个可以通过(key1.key2.key3)形式获取嵌套字典值的方法,如有不对或者需要优化的地方欢迎指出。

def get_dict_value(date, keys, default=None):
#default=None,在key值不存在的情况下,返回None
keys_list = keys.split('.')
#以“.”为间隔,将字符串分裂为多个字符串,其实字符串为字典的键,保存在列表keys_list
if isinstance(date,dict):
#如果传入的数据为字典
dictionary = dict(date)
#初始化字典
for i in keys_list:
#按照keys_list顺序循环键值
try:
if dictionary.get(i) != None:
dict_values = dictionary.get(i)
#如果键对应的值不为空,返回对应的值
elif dictionary.get(i) == None:
dict_values = dictionary.get(int(i))
#如果键对应的值为空,将字符串型的键转换为整数型,返回对应的值
except:
return default
#如果字符串型的键转换整数型错误,返回None
dictionary = dict_values
return dictionary
else:
#如果传入的数据为非字典
try:
dictionary = dict(eval(date))
#如果传入的字符串数据格式为字典格式,转字典类型,不然返回None
if isinstance(dictionary,dict):
for i in keys_list:
#按照keys_list顺序循环键值
try:
if dictionary.get(i) != None:
dict_values = dictionary.get(i)
#如果键对应的值不为空,返回对应的值
elif dictionary.get(i) == None:
dict_values = dictionary.get(int(i))
#如果键对应的值为空,将字符串型的键转换为整数型,返回对应的值
except:
return default
#如果字符串型的键转换整数型错误,返回None
dictionary = dict_values
return dictionary
except:
return default

运行结果:
一:字典类型数据。

二:字典类型数据,包含的键为数字。

三:json类型的字符串。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 18 条回复 时间 点赞

测试下这种 {"key":[{"subkey":"value"}]}

有个朋友分享过这段代码,大家可以试试。

class obj(object):
def __init__(self, d):
for a, b in d.items():
if isinstance(b, (list, tuple)):
setattr(self, a, [obj(x) if isinstance(x, dict) else x for x in b])
else:
setattr(self, a, obj(b) if isinstance(b, dict) else b)

d = {'a':1, 'b':{'c':2}, 'd':[{'e':1}]}

res = obj(d)
print res.a
print res.b.c
print res.d[0].e

python的json模块不能搞这些事么?

可以参考这个addict

重拾 #5 · March 22, 2017 作者
chen 回复

👍 原来还有这个库,实现起来好简单,非常感谢

重拾 #6 · March 22, 2017 作者
zragon 回复

给力

重拾 #7 · March 22, 2017 作者
孙高飞 回复

json模块只用过来字符转字典,字典转字符,好像没看到有取值的

chen 回复

感谢分享

json对象比字典对象复杂度高一点,接口测试里处理json可以这样做:

json.loads()方法可以将字符串转化成json对象,如果不方便转换的类型,比如数据库涉及的date,timestamp类型,也可以通过json.JSONEncoder自己定义转化。

python里json数据的取值也比较简单 ,基本就是 ob[key][index]这样。

楼主的例子

ob = json.loads(data_a)
print ob["2"]["b"]["c"]

不过,等等,发现一个令我惊恐的问题,楼主给的字符串,第一层的key是1?这个符合json的规范?
所以我刚试了一下,楼主的字符串用json模块loads不进,orz 我错了

@xeon 楼主,请教个问题,我的接口要求传入的json串按顺序,否则接口不认。python 读取字典是随机的,那么json串里面的参数也是随机排列的,有没有什么好的方法 。

独行数息 回复

json.dumps()方法有个参数sort_keys

剪烛 回复

这个只能按首字母排序 。而不是自定义顺序

重拾 #14 · March 24, 2017 作者
剪烛 回复

是的,key可能是字符,也可能是数字

独行数息 回复

自定义顺序或许可以看下OrderedDict?

重拾 #16 · March 24, 2017 作者
独行数息 回复

你参考一下

如果是这种嵌套里面有多个相同的key呢,如下面的second_key1和second_key2呢?
{
'first_ke1': 'a',
'first_key2': [{'second_key1': 'b1', 'second_key2': 'c1'}, {'second_key1': 'b2', 'second_key2': 'c2'}, {'second_key1': 'b3', 'second_key2': 'c3'}]
}

chen 回复

帮了大忙了,太感谢!

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up