功能
将字符串str当成有效的表达式来求值并返回计算结果。
用法
- 计算字符串中有效的表达式,并返回结果
>>> eval('pow(2,2)')
4
>>> eval('2 + 2')
4
- 将字符串转成相应的对象(如list、tuple、dict和string之间的转换)
>>> a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
>>> b = eval(a)
>>> b [[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
>>> a = "{1:'xx',2:'yy'}"
>>> c = eval(a)
>>> c {1: 'xx', 2: 'yy'}
>>> a = "(1,2,3,4)"
>>> d = eval(a)
>>> d (1, 2, 3, 4)
- 将利用反引号转换的字符串再反转回对象
>>> list1 = [1,2,3,4,5]
>>> `list1` '[1, 2, 3, 4, 5]'
>>> type(`list1`)
>>>> <type 'str'>
>>> type(eval(`list1`))
>>> <type 'list'>
>>> a = eval(`list1`)
>>> a [1, 2, 3, 4, 5]
缺点
安全性不够好。
想一想这种使用环境:需要用户输入一个表达式,并求值。
如果用户恶意输入,例如:
__import__('os').system('dir')
那么eval()之后,你会发现,当前目录文件都会展现在用户前面。
那么继续输入:
open('文件名').read()
代码都给人看了。获取完毕,一条删除命令,文件消失。哭吧!
怎么避免安全问题?
使用ast.literal_eval
>>> import ast
>>> a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
>>> b = ast.literal_eval(a)
>>> b [[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
>>> a = "{1:'xx',2:'yy'}"
>>> c = ast.literal_eval(a)
>>> c {1: 'xx', 2: 'yy'}
>>> a = "(1,2,3,4)"
>>> d = ast.literal_eval(a)
>>> d (1, 2, 3, 4)
与json.loads的区别
- json.loads与eval都能将s转成python中的对象,json.loads将json中的字符串转成unicode(types.UnicodeType),eval转成了str(types.StringType)。
- json.loads只能将存储形式为json串的字符转成python对象。
- json不认单引号,json中的字符串需要用双引号包起来
>>> dct="{'one':1}" >>> json.loads(dct) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/json/__init__.py", line 338, in loads return _default_decoder.decode(s) File "/usr/lib/python2.7/json/decoder.py", line 365, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/lib/python2.7/json/decoder.py", line 381, in raw_decode obj, end = self.scan_once(s, idx) ValueError: Expecting property name: line 1 column 2 (char 1)