当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python eval()用法及代码示例


在本教程中,我们将借助示例了解 Python eval() 方法。

eval() 方法解析传递给该方法的表达式并在程序中运行 python 表达式(代码)。

示例

number = 9

# eval performs the multiplication passed as argument
square_number = eval('number * number')
print(square_number)

# Output: 81

eval() 语法

用法:

eval(expression, globals=None, locals=None)

参数:

eval() 函数采用三个参数:

  • expression- 作为 Python 表达式解析和评估的字符串
  • globals(可选) - 字典
  • locals(可选)- 一个映射对象。字典是 Python 中标准且常用的映射类型。

globalslocals 的使用将在本文后面讨论。

返回:

eval() 方法返回从 expression 评估的结果。

示例 1:eval() 如何在 Python 中工作

x = 1
print(eval('x + 1'))

输出

2

在这里,eval() 函数计算表达式 x + 1 并且 print 用于显示该值。

示例 2:演示使用 eval() 的实际示例

# Perimeter of Square
def calculatePerimeter(l):
    return 4*l

# Area of Square
def calculateArea(l):
    return l*l

expression = input("Type a function: ")

for l in range(1, 5):
    if (expression == 'calculatePerimeter(l)'):
        print("If length is ", l, ", Perimeter = ", eval(expression))
    elif (expression == 'calculateArea(l)'):
        print("If length is ", l, ", Area = ", eval(expression))
    else:
        print('Wrong Function')
        break

输出

Type a function: calculateArea(l)
If length is  1 , Area =  1
If length is  2 , Area =  4
If length is  3 , Area =  9
If length is  4 , Area =  16

使用 eval() 时的警告

考虑使用 Unix 系统(macOS、Linux 等)并且您已导入 os 模块的情况。 os 模块提供了一种可移植的方式来使用操作系统函数,例如读取或写入文件。

如果您允许用户使用 eval(input()) 输入值,则用户可以使用以下命令发出命令来更改文件甚至删除所有文件: os.system('rm -rf *')

如果您在代码中使用eval(input()),最好检查用户可以使用哪些变量和方法。您可以使用 dir() method 查看哪些变量和方法可用。

from math import *
print(eval('dir()'))

输出

['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'os', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

限制 eval() 中可用方法和变量的使用

通常情况下,expression(eval() 的第一个参数)中使用的所有可用方法和变量可能都不需要,甚至可能存在安全漏洞。您可能需要限制对 eval() 使用这些方法和变量。您可以通过将可选的 globalslocals 参数(字典)传递给 eval() 函数来实现。

1.当globals和locals参数都省略时

如果两个参数都被省略(如我们之前的示例中),则 expression 在当前范围内执行。您可以使用以下代码检查可用的变量和方法:

print(eval('dir()')

2.传递globals参数; locals 参数被省略

globalslocals 参数(字典)分别用于全局和局部变量。如果省略locals 字典,则默认为globals 字典。意思是,globals 将用于全局和局部变量。

注意:您可以使用 Python 检查当前的全局和本地字典globalslocals内置方法分别。

示例 3:将空字典作为全局参数传递

from math import *
print(eval('dir()', {}))

# The code will raise an exception
print(eval('sqrt(25)', {}))

输出

['__builtins__']
Traceback (most recent call last):
  File "<string>", line 5, in <module>
    print(eval('sqrt(25)', {}))
  File "<string>", line 1, in <module>
NameError: name 'sqrt' is not defined

如果您将空字典作为 globals 传递,则只有 __builtins__ 可用于 expression (eval() 的第一个参数)。

即使我们在上述程序中导入了math 模块,expression 也无法访问 math module 提供的任何函数。

示例 4:使某些方法可用

from math import *
print(eval('dir()', {'sqrt': sqrt, 'pow': pow}))

输出

['__builtins__', 'pow', 'sqrt']

在这里,表达式只能使用 sqrt()pow() 方法以及 __builtins__

也可以根据您的意愿更改 expression 可用方法的名称:

from math import *
names = {'square_root': sqrt, 'power': pow}
print(eval('dir()', names))

# Using square_root in Expression
print(eval('square_root(9)', names))

输出

['__builtins__', 'power', 'square_root']
3.0

在上述程序中,square_root() 使用 sqrt() 计算平方根。但是,尝试直接使用sqrt() 会引发错误。

示例 5:限制使用 内置s

您可以限制在expression 中使用__builtins__,如下所示:

eval(expression, {'__builtins__': None})

3. 传递全局和局部字典

您可以通过传递locals 字典使所需的函数和变量可供使用。例如:

from math import *

a = 169
print(eval('sqrt(a)', {'__builtins__': None}, {'a': a, 'sqrt': sqrt}))

输出

13.0

在这个程序中,expression 只能有sqrt() 方法和变量a。所有其他方法和变量均不可用。

通过传递globalslocals 字典来限制eval() 的使用将使您的代码安全,特别是当您使用用户向eval() 方法提供的输入时。

注意:有时,eval()即使名称有限,也不安全。当一个对象及其方法可以访问时,几乎可以做任何事情。唯一安全的方法是验证用户输入。

相关用法


注:本文由纯净天空筛选整理自 Python eval()。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。