https://zhuanlan.zhihu.com/p/29881075
众所周知在Python中,如果要将字符串型的list,tuple,dict转变成原有的类型呢? 这个时候你自然会想到eval. eval函数在python中做数据类型的转换还是很有用的。它的作用就是把数据还原成它本身或者是能够转化成的数据类型.下面来看看示例代码:
# str => list
a = '[1, 2, 3, 4]'
res = eval(a)
print(a, type(a)) # [1, 2, 3, 4] <class 'str'>
print(res, type(res)) # [1, 2, 3, 4] <class 'list'>
# str => dict
info1 = '{"a": "97", "b":"98", "c":"99", "d":"100"}'
info2 = "{'a':'97', 'b':'98', 'c':'99', 'd':'100'}"
res1 = ast.eval(info1)
res2 = ast.eval(info2)
print(res1, type(res1)) # {'a': '97', 'b': '98', 'c': '99', 'd': '100'} <class 'dict'>
print(res2, type(res2)) # {'a': '97', 'b': '98', 'c': '99', 'd': '100'} <class 'dict'>
此外,eval()还可以对字符串的输入直接进行计算
eval("12 + 1") # 13
从上面来看,eval功能可谓非常强大,即可以做string与list,tuple,dict之间的类型转换,还可以做计算器使用!更有甚者,可以对她能解析的字符串都做处理,而不顾忌可能带来的后果!所以说eval强大的背后,是巨大的安全隐患!!!
比如说,用户恶意输入下面的字符串
open(r'D://filename.txt', 'r').read()
__import__('os').system('dir')
__import__('os').system('rm -rf /etc/*')
那么eval就会不管三七二十一,显示你电脑目录结构,读取文件,删除文件…如果是格盘等更严重的操作,她也会照做不误!!!
所以这里就引出了另外一个安全处理方式ast.literal_eval
简单点说ast模块就是帮助Python应用来处理抽象的语法解析的。而该模块下的literal_eval()函数:则会判断需要计算的内容计算后是不是合法的python类型,如果是则进行运算,否则就不进行运算。
比如说上面的计算操作,及危险操作,如果换成了ast.literal_eval(),都会拒绝执行。
所以出于安全考虑,对字符串进行类型转换的时候,最好使用ast.literal_eval()函数!