3-2python语法基础-函数-内置函数-Python中函数eval和ast.literal_eval的区别详解
eval用法
python中eval的用法:python eval() 函数的功能:将字符串str当成有效的表达式来求值并返回计算结果。
eval()函数用来执行一个字符串表达式,并返回表达式的值。
python中eval函数的用法十分的灵活,但也十分危险,安全性是其最大的缺点。
用途1:将字符串型的list,tuple,dict转变成原有的类型
在Python中,如果要将字符串型的list,tuple,dict转变成原有的类型呢? 这个时候你自然会想到eval. eval函数在python中做数据类型的转换还是很有用的。它的作用就是把数据还原成它本身或者是能够转化成的数据类型.下面来看看示例代码:
string <==> tuple
str_tuple = '(1,2,3)'
print(eval(str_tuple)) # (1, 2, 3)
print(type(eval(str_tuple))) # <class 'tuple'>
string <==> list
str_list = '[1,2,3]'
print(eval(str_list)) # [1, 2, 3]
print(type(eval(str_list))) # <class 'list'>
string <==> dict
str_dict = "{'a':1,'b':2}"
print(eval(str_dict)) # {'a': 1, 'b': 2}
print(type(eval(str_dict))) # <class 'dict'>
也就是说,使用eval可以实现从元祖,列表,字典型的字符串到元祖,列表,字典的转换,
用途2:对表达式的结果进行计算,返回计算后的值
此外,eval还可以对字符
串型的输入直接计算。比如,她会将'1+1'的计算串直接计算出结果。
ret = eval("1+1")
print(ret) # 2
print(type(ret)) # <class 'int'>
eval的危险性!
从上面来看,eval功能可谓非常强大,即可以做string与list,tuple,dict之间的类型转换,还可以做计算器使用!更有甚者,可以对她能解析的字符串都做处理,而不顾忌可能带来的后果!所以说eval强大的背后,是巨大的安全隐患!!! 比如说,用户恶意输入下面的字符串
open(r'D://filename.txt', 'r').read()
__import__('os').system('dir')
__import__('os').system('rm -rf /etc/*')
示例:
ret = eval("__import__('os').system('ls')")
print(ret) # 0
print(type(ret)) # <class 'int'>
会执行这个语句,执行ls命令,很危险!!!
那么eval就会不管三七二十一,显示你电脑目录结构,读取文件,删除文件.....如果是格盘等更严重的操作,她也会照做不误!!!
ast.literal_eval
所以这里就引出了另外一个安全处理方式ast.literal_eval.
简单点说ast模块就是帮助Python应用来处理抽象的语法解析的。而该模块下的literal_eval()函数:则会判断需要计算的内容计算后是不是合法的python类型,如果是则进行运算,否则就不进行运算。
比如说上面的计算操作,及危险操作,如果换成了ast.literal_eval() ,都会拒绝执行。
报值错误,不合法的字符串!
而只会执行合法的Python类型,从而大大降低系统的危险性!
所以出于安全考虑,对字符串进行类型转换的时候,最好使用ast.literal_eval()函数!