eval 是Python的一个内置函数
作用:
(1)若传入参数字符串,为纯净字符串,则去掉纯净字符串的外衣,将数值返回给LHS
(2)若传入参数字符串,为一个表达式,那么将表达式进行RHS计算,并传给LHS
(3)若传入参数字符串,为列表字符串、字典字符串、元组字符串,则转化成相应列表、字典、元组
eval的语法格式如下:
eval(expression[, globals[, locals]])
expression : 字符串
globals : 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
locals : 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
一、计算功能
二、转化功能
一、字符串转换成列表
a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
print(type(a))
b = eval(a)
print(type(b))
print(b)
<class 'str'>
<class 'list'>
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
[Finished in 180ms]
二、字符串转换成字典
a = "{1: 'a', 2: 'b'}"
print(type(a))
b = eval(a)
print(type(b))
print(b)
<class 'str'>
<class 'dict'>
{1: 'a', 2: 'b'}
三、字符串转换成元组
a = "([1,2], [3,4], [5,6], [7,8], (9,0))"
print(type(a))
b=eval(a)
print(type(b))
print(b)
<class 'str'>
<class 'tuple'>
([1, 2], [3, 4], [5, 6], [7, 8], (9, 0))
python中eval函数的用法十分的灵活,但也十分危险,安全性是其最大的缺点。
eval的语法格式如下:
eval(expression[, globals[, locals]])
expression : 字符串
globals : 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
locals : 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
结合globals和locals看看几个例子
传递globals参数值为{“age”:1822},
eval("{'name':'linux','age':age}",{"age":1822})
输出结果:{‘name’: ‘linux’, ‘age’: 1822}
再加上locals变量
age=18
eval("{'name':'linux','age':age}",{"age":1822},locals())
根据上面两个例子可以看到当locals参数为空,globals参数不为空时,查找globals参数中是否存在变量,并计算。
当两个参数都不为空时,先查找locals参数,再查找globals参数,locals参数中同名变量会覆盖globals中的变量。
![](https://i-blog.csdnimg.cn/blog_migrate/78d1028ad7c38742b6cac6abdbe62ef7.png)
三、危险之处
eval虽然方便,但是要注意安全性,可以将字符串转成表达式并执行,就可以利用执行系统命令,删除文件等操作。
假设用户恶意输入。比如:
eval("__import__('os').system('ls /Users/chunming.liu/Downloads/')")
那么eval()之后,你会发现,当前文件夹文件都会展如今用户前面。这句其实相当于执行了
os.system('ls /Users/chunming.liu/Downloads/')
那么继续输入:
eval("__import__('os').system('cat /Users/chunming.liu/Downloads/tls_asimov_cert.pem')")
代码都给人看了。
再来一条删除命令,文件消失。比如
eval("__import__('os').system('rm /Users/chunming.liu/Downloads/车辆转发测试.png')")
所以使用eval,一方面享受他的了灵活性同时,也要注意安全性。