一、eval函数
eval()官方文档里面给出来的功能解释是:将字符串string对象转化为有效的表达式参与求值运算返回计算结果
实例:
>>> s='8*8'
>>> eval(s)
64
>>> eval('2+5*4')
22
>>> x=1
>>> y=4
>>> eval('x+y')
5
>>> eval('98.9')
98.9
>>> eval('9.9\n')
9.9
>>> eval('9.9\n\t\r \t\r\n')
9.9
最有用的一个是eval可以将字符串转换成字典,列表,元组=,函数在 Python 中做数据类型的转换还是很有用的。它的作用就是把数据还原成它本身或者是能够转化成的数据类型
>>> l = "[2,3,4,5]"
>>> ll=eval(l)
>>> ll
[2, 3, 4, 5]
>>> type(ll)
<type 'list'>
>>> d="{'name':'python','age':20}"
>>> dd=eval(d)
>>> type(dd)
<type 'dict'>
>>> dd
{'age': 20, 'name': 'python'}
>>> t='(1,2,3)'
>>> tt=eval(t)
>>> type(tt)
<type 'tuple'>
>>> tt
(1, 2, 3)
从上面来看,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.
实际问题:
报错:
SyntaxError: unexpected EOF while parsing
eval在处理空字符串时会返回EOF错误,或者语法格式问题,缺括号等等
二、ast.literal_eval
ast.literal_eval是python针对eval方法存在的安全漏洞而提出的一种安全处理方式。
简单点说ast模块就是帮助Python应用来处理抽象的语法解析的。而该模块下的literal_eval()函数:则会判断需要计算的内容计算后是不是合法的Python类型,如果是则进行运算,否则就不进行运算。
比如下面查看系统文件的操作就会被拒绝,而只会执行合法的python类型,从而大大降低了系统的危险性
import ast
res = ast.literal_eval('1 + 1')
print(res)
# 2
res = ast.literal_eval('[1, 2, 3, 4]')
print(type(res))
# <class 'list'>
print(res)
# [1, 2, 3, 4]
res = ast.literal_eval("__import__('os').system('ls')")
# 报错如下:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/didi/.pyenv/versions/3.6.4/lib/python3.6/ast.py", line 85, in literal_eval
return _convert(node_or_string)
File "/Users/didi/.pyenv/versions/3.6.4/lib/python3.6/ast.py", line 84, in _convert
raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x10e63ca58>
所以出于安全考虑,对字符串进行类型转换的时候,最好使用ast.literal_eval()