1、函数原型:
eval(expression[, globals=None[, locals=None]])
功能:将字符串str当成有效的表达式来求值并返回计算结果。
2、参数:
expression:需要求值的字符串表达式
globals:可选参数,变量作用域,全局命名空间,必须是字典对象
locals:可选参数,变量作用域,局部命名空间,必须是字典对象
3、返回值:
返回表达式计算结果。
4、举例:
1)不使用可选参数时,eval()函数直接对expression求结果,如下例1和例2:
# 例1:使用eval求字符串数学表达式的值
x = 7
print 'eval(\'x+7\')的值是', eval('x+7')
print 'eval(\'x**2\')的值是', eval('x**2')
输出结果:
eval('x+7')的值是 14
eval('x**2')的值是 49
# 例2:使用eval将字符串转换为其他形式
s1 = "{'name':'lmm', 'age':7}"
s2 = eval(s1)
print 's1为', s1, ',s1的类型为', type(s1)
print 's2为', s2, ',s2的类型为', type(s2)
s3 = "[[1, 2], [2, 3, 4]]"
s4 = eval(s3)
print 's3为', s3, ',s3的类型为', type(s3)
print 's4为', s4, ',s4的类型为', type(s4)
输出结果:
s1为 {'name':'lmm', 'age':7} ,s1的类型为 <type 'str'>
s2为 {'age': 7, 'name': 'lmm'} ,s2的类型为 <type 'dict'>
s3为 [[1, 2], [2, 3, 4]] ,s3的类型为 <type 'str'>
s4为 [[1, 2], [2, 3, 4]] ,s4的类型为 <type 'list'>
2)使用可选参数时,eval()函数的使用:
首先了解一下python中使用一个变量时,在命名空间中的查找顺序:当一行代码要使用x的值时,python会到所有可用的命名空间去查找变量,按照如下顺序:
1)局部命名空间:特指当前函数或类的方法和变量。如果函数定义了一个局部变量x,或一个参数x,python将使用它,然后停止搜索,否则,在全局命名空间中进行搜索;
2)全局命名空间:特指当前的模块。如果模块定义了一个名为x的变量,函数或类,python将使用它,然后停止搜索,否则,在内置命名空间中搜索;
3)内置命名空间:对每个模块都是全局的。作为最后的尝试,python将假设x是内置函数或变量。
python的全局命名空间存储在一个叫globals()的dict对象中,局部命名空间存储在一个叫locals()的dict对象中。可以通过print locals()来查看一个函数体内的所有变量名和变量值。
eval()函数的第二个参数和第三个参数即指定了使用变量时应查找的命名空间。
# 例3:使用自己指定的字典作为eval的第二和第三个参数
a = 1
d1 = {'a': 20}
d2 = {'a': 30}
d3 = {'b': 40}
print eval('a+1') # 式1
print eval('a+1', d1) # 式2
print eval('a+1', d1, d2) # 式3
print eval('a+1', d1, d3) # 式4
输出结果:
2
21
31
21
可见,在式1中,直接使用全局变量x的值1;
在式2中,指定了一个搜索字典,先在该字典中搜索有无键a;
在式3中,指定了两个搜索字典,先搜索d2,在d2中搜索到了无需再搜索d1;
在式4中,指定了两个搜索字典,先搜索d3,在d2中搜索到了。
若指定了第二个和第三个参数,但是在其中搜索不到字符串表达式中使用的变量,会报错。
# 例4:使用python全局命名空间和局部命名空间作为第二个第三个参数
x = 1
y = 1
num1 = eval('x+y') # 式5
print 'num1 = ', num1
def func():
x, y = 2, 2
num2 = eval('x+y') # 式6
print 'num2 = ',num2
num3 = eval('x+y', globals()) # 式7
print 'num3 = ', num3
num4 = eval('x+y', globals(), locals()) # 式8
print 'num4 = ', num4
num5 = eval('x+y', locals(), globals()) # 式9
print 'num5 = ', num5
func()
输出结果:
num1 = 2
num2 = 4
num3 = 2
num4 = 4
num5 = 2
可见,省略后两个参数时,eval()查找变量的值时,eval()会先搜索第二个参数指定的字典,再搜索第三个参数指定的字典。
5、缺点:
存在安全隐患。
想一想这种使用环境:需要用户输入一个表达式,然后系统对该表达式求值。
如果用户恶意输入,例如:
__import__('os').system('dir')
那么eval()之后,你会发现,当前目录文件都会展现在用户前面。加入用户再输入open(filename.read()),就会读取用户的文件信息。读完之后,甚至可能输入一条删除命令删除文件...后果不堪设想!
# 存在安全隐患的eval使用
eval("__import__('os').system('dir')")
eval("open(filename).read()")
6、参考:
Python:eval的妙用和滥用:https://blog.csdn.net/zhanh1218/article/details/37562167?utm_source=tuicool&utm_medium=referral
python eval():https://www.cnblogs.com/dadadechengzi/p/6149930.html
网友评论