使用 python 中的数学模块安全地使用 eval 进行计算

Safely using eval to calculate using the math module in python

我想从用户输入的字符串中获取计算结果,同时使用 math 函数,例如 sinceil。我也希望能够以 sin(30) 而不是 math.sin(30) 的方式进行。我想做

from math import *

可以,因为当我全部导入时,它显示为内置函数,并且导入了内置函数。但是,当我 运行 代码时,它表明数学函数在 eval()

中不起作用
>>> from math import *
>>> sin
<built-in function sin>
>>> print
<built-in function print>
>>> eval("sin(30)", {}, {})
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    eval("sin(30)", {}, {})
  File "<string>", line 1, in <module>
NameError: name 'sin' is not defined

我是否必须手动添加所有数学函数,或者有更简单的方法吗?

关于“安全”,这取决于你的意思。您可以很容易地提供对全局环境的访问权限,让表达式可以访问您导入的任何内容。但是没有什么可以阻止用户输入可以执行意外操作的表达式,因此如果表达式来自不受信任的用户,那么您应该避免使用 eval.

话虽如此,您可以使您的示例按如下方式工作:

>>> from math import *
>>> eval("sin(30)", globals())
-0.9880316240928618
>>> 

请注意,在此示例中,30 被解释为弧度而不是度数。

$ echo -e  'import math\nmathok={k: v for k, v in math.__dict__.items() if not k.startswith("__")}\nprint(eval("3*pi",{"__builtins__": {}},mathok))' | python               
9.42477796076938