Python eval()函数

时间:2020-02-23 14:42:40  来源:igfitidea点击:

Python eval()函数用于将表达式字符串解析为python表达式,然后执行它。

Python eval()函数

Python eval()函数签名为:

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

expression –必需的字符串参数,正在将其解析并作为python表达式执行。

globals –字典,用于指定可用于执行的表达式。
如果未使用'__builtins__':None元素明确限制,则可以使用标准的内置方法。

locals –用于指定eval()函数可用的局部变量和方法。

Python eval()示例

我们首先来看一个简单的python eval()函数示例。

x = 1

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

print(eval('x+2'))

输出:

True
3

带有用户输入的Python eval()

上面的eval()函数示例非常有限,不能证明其功能合理。
eval()函数的功能在于语句的动态执行。
我们可以使用eval()函数执行任意代码对象。

让我们看一个更复杂的示例,在该示例中,我们将要求用户输入要执行的功能。

# eval() with user input
from math import *

for l in range(1, 3):

  func = input("Enter Math Function to Evaluate:\n")
  try:
      print(eval(func))
  except Exception as ex:
      print(ex)
      break
print('Done')

下图显示了上述python脚本的示例执行。

没有评估功能,我们将无法执行用户输入的命令。
这是eval()函数的功能。

使用eval()函数的安全风险

强大的力量来了,如果您允许将用户输入作为命令来执行,那么伟大的责任就是如此。

如果我们导入了os模块并且用户输入os.system('rm -rf /')命令来执行该怎么办?这将开始删除系统文件并破坏我们的环境。

这就是为什么当您使用eval()函数执行用户输入代码时,需要确保首先检查用户输入的数据,如果这些数据没问题,那么只能执行它。
这是全局和局部参数派上用场的时候。

Python eval()全局变量和局部变量

在决定应将哪些函数提供给eval()之前,我们需要找出全局和局部范围内存在的所有函数和变量。
我们可以使用内置函数globals(),locals()和dir()找到这些信息。

让我们看一个示例,我们将找出全局和局部范围内可用的函数和变量。

from math import *

def square_root(n):
 return sqrt(n)

print(globals()) # dictionary representing the current global symbol table.
print(locals()) # dictionary representing the current local symbol table.
print(dir()) # list of names in the current local scope

输出:

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x105b11400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/hyman/Documents/PycharmProjects/BasicPython/basic_examples/eval_example.py', '__cached__': None, 'acos': <built-in function acos>, 'acosh': <built-in function acosh>, 'asin': <built-in function asin>, 'asinh': <built-in function asinh>, 'atan': <built-in function atan>, 'atan2': <built-in function atan2>, 'atanh': <built-in function atanh>, 'ceil': <built-in function ceil>, 'copysign': <built-in function copysign>, 'cos': <built-in function cos>, 'cosh': <built-in function cosh>, 'degrees': <built-in function degrees>, 'erf': <built-in function erf>, 'erfc': <built-in function erfc>, 'exp': <built-in function exp>, 'expm1': <built-in function expm1>, 'fabs': <built-in function fabs>, 'factorial': <built-in function factorial>, 'floor': <built-in function floor>, 'fmod': <built-in function fmod>, 'frexp': <built-in function frexp>, 'fsum': <built-in function fsum>, 'gamma': <built-in function gamma>, 'gcd': <built-in function gcd>, 'hypot': <built-in function hypot>, 'isclose': <built-in function isclose>, 'isfinite': <built-in function isfinite>, 'isinf': <built-in function isinf>, 'isnan': <built-in function isnan>, 'ldexp': <built-in function ldexp>, 'lgamma': <built-in function lgamma>, 'log': <built-in function log>, 'log1p': <built-in function log1p>, 'log10': <built-in function log10>, 'log2': <built-in function log2>, 'modf': <built-in function modf>, 'pow': <built-in function pow>, 'radians': <built-in function radians>, 'remainder': <built-in function remainder>, 'sin': <built-in function sin>, 'sinh': <built-in function sinh>, 'sqrt': <built-in function sqrt>, 'tan': <built-in function tan>, 'tanh': <built-in function tanh>, 'trunc': <built-in function trunc>, 'pi': 3.141592653589793, 'e': 2.718281828459045, 'tau': 6.283185307179586, 'inf': inf, 'nan': nan, 'square_root': <function square_root at 0x105b6a2f0>}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x105b11400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/hyman/Documents/PycharmProjects/BasicPython/basic_examples/eval_example.py', '__cached__': None, 'acos': <built-in function acos>, 'acosh': <built-in function acosh>, 'asin': <built-in function asin>, 'asinh': <built-in function asinh>, 'atan': <built-in function atan>, 'atan2': <built-in function atan2>, 'atanh': <built-in function atanh>, 'ceil': <built-in function ceil>, 'copysign': <built-in function copysign>, 'cos': <built-in function cos>, 'cosh': <built-in function cosh>, 'degrees': <built-in function degrees>, 'erf': <built-in function erf>, 'erfc': <built-in function erfc>, 'exp': <built-in function exp>, 'expm1': <built-in function expm1>, 'fabs': <built-in function fabs>, 'factorial': <built-in function factorial>, 'floor': <built-in function floor>, 'fmod': <built-in function fmod>, 'frexp': <built-in function frexp>, 'fsum': <built-in function fsum>, 'gamma': <built-in function gamma>, 'gcd': <built-in function gcd>, 'hypot': <built-in function hypot>, 'isclose': <built-in function isclose>, 'isfinite': <built-in function isfinite>, 'isinf': <built-in function isinf>, 'isnan': <built-in function isnan>, 'ldexp': <built-in function ldexp>, 'lgamma': <built-in function lgamma>, 'log': <built-in function log>, 'log1p': <built-in function log1p>, 'log10': <built-in function log10>, 'log2': <built-in function log2>, 'modf': <built-in function modf>, 'pow': <built-in function pow>, 'radians': <built-in function radians>, 'remainder': <built-in function remainder>, 'sin': <built-in function sin>, 'sinh': <built-in function sinh>, 'sqrt': <built-in function sqrt>, 'tan': <built-in function tan>, 'tanh': <built-in function tanh>, 'trunc': <built-in function trunc>, 'pi': 3.141592653589793, 'e': 2.718281828459045, 'tau': 6.283185307179586, 'inf': inf, 'nan': nan, 'square_root': <function square_root at 0x105b6a2f0>}
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'square_root', 'tan', 'tanh', 'tau', 'trunc']

eval()可以访问很多功能。
它们大多数来自__builtins__和math模块。

让我们看看在eval函数中将" globals"值指定为空字典时会发生什么。

print(eval('dir()',{}))

输出:

['__builtins__']

因此,内置方法仍可用于eval函数。
如果只想限制对某些内置方法的访问,则可以为全局变量指定其值。
例如,下面的代码允许eval()函数仅执行min内置函数。

print(eval('min(1,2)',{'__builtins__':{'min': min}})) # 1

让我们看另一个示例,其中我提供了locals值并禁用了eval()的所有内置函数访问。

y=5
print(eval('y+1',{'__builtins__': None}, {'y': y})) # 6

让我们看一个最后的示例,在该示例中,我仅允许访问数学模块中的几种方法。
我们还将square_root映射到sqrt函数,以提高人类可读性。

from math import *

for l in range(1, 3):
  func = input("Enter Math Function to Evaluate.\nAllowed Functions are: square_root(x) and pow(x,y):\n")
  try:
      print(eval(func, {'square_root': sqrt, 'pow': pow}))
  except Exception as ex:
      print(ex)
      break
print('Done')

示例输出:

Enter Math Function to Evaluate.
Allowed Functions are: square_root(x) and pow(x,y):
square_root(16)
4.0
Enter Math Function to Evaluate.
Allowed Functions are: square_root(x) and pow(x,y):
log10(100)
name 'log10' is not defined
Done

您是否注意到上述代码中的任何缺陷?

我没有为内置函数指定任何内容,因此它们可用于eval()函数。

下面是另一个运行示例,以显示可以执行内置函数。

Enter Math Function to Evaluate.
Allowed Functions are: square_root(x) and pow(x,y):
min(5,4)
4
Enter Math Function to Evaluate.
Allowed Functions are: square_root(x) and pow(x,y):
max(10,20)
20