如何在 Python 3.5 中正确限制 eval 中的 __builtins__?

How to properly limit __builtins__ in eval in Python 3.5?

在 python 2.7 中,我可以通过将全局定义为 {'__builtins__': None} 来限制 eval 使用的 __builtins__ 命名空间。这似乎在 Python 3.5.

中不起作用

Python 2.7 正确给出了 NameError:

In [1]: eval('round', {'__builtins__': None})
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-14-dc1cae9c6b26> in <module>()
----> 1 eval('round', {'__builtins__': None})

<string> in <module>()

NameError: name 'round' is not defined

Python 3.5 给出以下内容:

In [1]: eval('round', {'__builtins__': None})
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-83a8846287f1> in <module>()
----> 1 eval('round', {'__builtins__': None})

<string> in <module>()

TypeError: 'NoneType' object is not subscriptable

两者都给出了以下内容的正确输出:

In [1]: eval('round')
Out[1]: <function round>

如何正确限制 __builtins__ 或解决此问题?

您可以将其设置为空字典:

eval('round', {'__builtins__': {}})

这将重现您在 Python 2.x 中获得的 NameError。但是,沙盒 Python,无论是 2 还是 3,都是 inherently hard problem. If possible, you should use something less powerful like ast.literal_eval() 而不是 eval()