【发布时间】:2020-10-31 03:14:04
【问题描述】:
我想从用户输入的字符串中获取计算结果,同时使用sin 或ceil 等math 函数。我也希望能够以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。 -
除了上述之外,没有什么比任何其他使用 eval 更安全的了。不确定标题中的
safely指的是什么。 -
"当我全部导入时,它显示为内置函数,并且内置函数被导入" - "内置函数 sin" 中的 "built-in" 表示它是用C. 这与它是否在内置命名空间中可用完全无关。不幸的是,“内置”在 Python 中意味着多个不相关的东西。 (此外,使内置名称自动可用的机制与导入无关。)
-
即使命名空间为空,恶意代码也可以执行
().__class__.__base__.__subclasses__()[-1].__init__.__globals__['__builtins__']['__import__']('os').system('install ransomware or something')之类的操作来运行任意shell 命令并做出可怕的事情。eval根本上是错误的工具。这很方便,但是错了。 -
@tdelaney:如果
__builtins__不存在于提供的全局变量中,eval会为评估代码提供默认内置函数。但是,即使您明确将代码设为空__builtins__,我的评论之类的内容仍然有效,因为它甚至不依赖于可用的内置名称。