为什么我能从'eval'中调用'print
对于这段代码:
#!/usr/bin/python
src = """
print '!!!'
import os
"""
obj = compile(src, '', 'exec')
eval(obj, {'__builtins__': False})
我得到的输出是:
!!!
Traceback (most recent call last):
File "./test.py", line 9, in <module>
eval(obj, {'__builtins__': False})
File "", line 3, in <module>
ImportError: __import__ not found
‘print’和‘import’都是语言的基本构造。为什么‘eval’限制使用‘import’,但不限制‘print’呢?
附注:我使用的是Python 2.6
更新:问题不是“为什么import不工作?”而是“为什么print可以工作?”这背后是否有一些架构上的限制或者其他原因?
4 个回答
0
import
是用来调用一个叫做 __import__
的全局函数;如果找不到这个函数,import
就会失败。
print
则不需要依赖任何全局变量来完成它的工作。这就是为什么在你的例子中,print
能正常工作,即使你没有使用可用的 __builtins__
。
2
在你的 eval
里,调用 import
是成功的,但 import
实际上是使用了内置的 __import__
方法,而你在 exec
中把这个方法给禁用了。这就是你看到的原因。
ImportError: __import__ not found
print
不依赖任何内置方法,所以可以正常工作。
你可以通过类似下面的方式,从内置中传递 __import__
:
eval(obj, {'__builtins__' : {'__import__' :__builtins__.__import__}})
7
__import__
方法是通过 import
这个关键词来调用的: python.org
如果你想要能够导入一个模块,你需要把 __import__
方法放在内置函数里:
src = """
print '!!!'
import os
"""
obj = compile(src, '', 'exec')
eval(obj, {'__builtins__': {'__import__':__builtins__.__import__}})