在使用Python代码进行自动化测试的时候,总是会遇到一些数据类型需要进行转化,比如做接口测试的时候从excel表里读取出来的数据就是字符串,但是需要用代码发送接口请求就需要转化为字典。那么这种场景可以怎么进行转化呢?
有如下方法都可以实现字符串转化为字典:
- 使用
eval()
函数 - 使用
ast.literal_eval()
函数 - 使用
json.loads()
函数
我们来分别解释一下这三种方法如何工作的。
eval()函数
eval函数是Python中做数据类型转化用的比较多的方法。他的作用就是把数据还原成它本身或者能够转化的数据类型。它可以运算字符串里的Python的表达式。
我们来看如下的案例:
1)eval获取字符串里的元组
a = '(1,2,3,4)'
a = eval(a)
print(a,type(a))
结果:
(1, 2, 3, 4) <class 'tuple'>
2)eval获取字符串里的字典
a = '{"name":"lemon","passwd":"123456"}'
a = eval(a)
print(a,type(a))
结果:
{'name': 'lemon', 'passwd': '123456'} <class 'dict'>
3) eval可以运算字符串里的Python表达式:
a = '5 > 6'
print(eval(a))
结果:False
甚至可以完成如下的功能,通过变量内容作为函数名字,使用eval转化后可以直接调用函数:
# 赋值函数名称
a = "b()"
# 定义函数
def b():
print(123)
# 通过变量调用函数
eval(a)
由上可见:eval()函数的功能还是非常的强大的,不过也存在一些安全隐患和问题:
- 首先,它对所有能解析的字符串都做处理(比如读取文件,路径,目录, 删除文件等),不管三七二十一,直接显示电脑目录,读取文件,删除文件等都会照做不误。所以是有些安全隐患的。
read_path = "__import__('os').getcwd()"
print("正常输出:",read_path)
print("转换输出:",eval(read_path))
结果:
正常输出: __import__('os').getcwd()
转换输出: D:\Pycharm_Project\pythonProject70\day16接口测试电商项目实战\01_扩展知识
- 其次,因为eval会自动运算字符串里的Python表达式,所以如果对方引号里不是合法的Python表达式的时候,就会报错了:
- 如下案例: false不是Python合法的表达式,用eval直接转化,就会报错了。
a = '{"name:":"lemon","age":false}'
print(eval(a))
结果:
NameError: name 'false' is not defined
ast.literal_eval()函数
这个ast模块是用来帮助Python应用开处理抽象的语法解析的,literal_eval()是该模块下的函数,会判断需要计算的内容计算后是不是合法的Python类型,如果是则进行运算,否则就不进行运行。
所以,这个函数可以更加安全地解析字符串中的Python字面量结构,会判断需要计算的内容计算后是不是合法的python类型,相较于eval()较安全。
比如上面的获取系统地址的字符串转化就会报错,不会直接去执行里面的代码:
read_path = "__import__('os').getcwd()"
print("正常输出:",read_path)
print("转换输出:",ast.literal_eval(read_path))
结果:
正常输出: __import__('os').getcw
ValueError: malformed node or string: <ast.Call object at 0x000001E8357EBE20>
而对于合法的python表达式,会进行运算和转化:
a = '{"name":"lemon","passwd":"123456"}'
a = ast.literal_eval(a)
print(a,type(a))
结果:
{'name': 'lemon', 'passwd': '123456'} <class 'dict'>
json.loads()函数
json库是Python的第三方库,json.loads()函数是用来读取json的字符串类型的数据,并且将读取的结果返回为python的dict对象。
它只是纯粹的将json字符串转换成python字典,无法进行引号里的计算功能。
转化字符串为字典:
string = '{"a": 1, "b": 2, "c": 3}'
dict1 = json.loads(string)
print(dict1,type(dict1))
结果:
{'a': 1, 'b': 2, 'c': 3} <class 'dict'>
但是这个json.loads的方法要注意,转化的字符串必须要是json语法规范的字符串,否则无法转化会报错:
string = '{"a": 1, "b": 2, "c": False}' # False不是json格式字符串
dict1 = json.loads(string)
print(dict1,type(dict1))
结果:
json.decoder.JSONDecodeError: Expecting value: line 1 column 23 (char 22)
json的格式要求,它的值只能是以下类型:
- 数字(整数或浮点数)
- 字符串(在双引号中): Python是单双三引号都可以,json只能双引号
- 逻辑值(true 或 false):注意Python的是大写的,False,True
- 数组(在中括号中)
- 对象(在大括号中)
- null : 注意Python的空是None
所以,json.loads方法遇到非以上的规范的字符串,转化都会失败报错。
总结对比区别:
ast.literal_eval()
:这个函数可以安全地解析字符串中的Python字面量结构,如列表、元组、字典等。它比eval()
更安全,因为它不会执行字符串中的任何代码。json.loads()
:这个函数用于将JSON格式的字符串转换为字典。它只能处理符合JSON格式的字符串,如果字符串中包含其他类型的数据,可能会抛出异常。eval()
:这个函数可以将字符串作为Python表达式进行求值,并返回结果。但是,由于它可能执行字符串中的任何代码,所以使用时需要特别小心,避免执行恶意代码。
总结:ast.literal_eval()
和json.loads()
适用于处理复杂的数据结构,而eval()
适用于处理简单的数据结构。在选择方法时,需要根据字符串的具体内容和需求来选择合适的方法。
欢迎来到testingpai.com!
注册 关于