Python:eval和exec函数的使用方法

eval()函数

eval是一个类似于exec的内置函数。把一个字符串当成一个表达式来执行, 返回表达式执行后的结果。
语法:

  eval(string_code, globals=None, locals=None)
x = 100
y = 200
# 执行x+y
# z = x + y
z1 = x + y
z2 = eval("x+y")

print(z1)
print(z2)

300
300

从上式可以看出,z1、z2语句不同,输出结果一样,eval就是能将字符串里内容执行后并返回

exec()函数

跟eval函数类似,能够将字符串当一个表达式来执行,但是不能返回执行的结果,而是一个None。
语法:

      exec(string_code, globals=None, locals=None)
# exec示例
x = 100
y = 200
# 执行x+y
# z = x + y
z1 = x + y
# 1, 注意字符串中引号的写法
# 2. 比对exec执行结果和代码执行结果
z2 = exec("print('x+y:', x+y)")

print(z1)
print(z2)

x+y: 300
300
None

eval()、exec()函数都能和print()函数一样,直接打印出内部的元素。

调用函数exec时只给它提供一个参数绝非好事。在大多数情况下,还应向它传递一个命名空间----用于放置变量的地方。否则代码将修改你的变量。例如代码使用了名称sqrt:

from math import sqrt
    exec("sqrt=1")
    sqrt(4)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
 in ()
      1 from math import sqrt
      2 exec("sqrt=1")
----> 3 sqrt(4)

TypeError: 'int' object is not callable

可见sqrt方法的变量名已被取代。那么为何要将字符串作为代码执行呢?函数主要用于动态地创建代码字符串。如果这种字符串来自其他地方(可能是用户),就几乎无法确定他将包含什么内容。因此为了安全起见,要提供一个字典以充当命名空间

可将命名空间视为放置变量的地方,类似于一个看不见的字典。当执行x=1时,将在当前命名空间存储键x和值1.

所以,可以在exec中添加第二个参数----字典,用作代码字符串的命名空间。

from math import sqrt
scope={}
exec('sqrt=1',scope)
print(sqrt(4))
print(scope['sqrt'])
---------------------------------------------------------------------------
2.0
1

很明显,可能带来破坏的代码没有覆盖函数sqrt,而通过exec执行赋值语句创建的变量位于scope中。

请注意,如果想将scope打印出来,将发现它包含很多内容,这是因为自动在其中添加了包含所有内置函数和值的字典__builtins__。

print(len(scope))
print(scope.keys())

2
dict_keys(['__builtins__', 'sqrt'])

你可能感兴趣的:(python,python,eval,exec)