2010-10-16 22 views
6

對於代碼 '打印':爲什麼我可以打電話從 'EVAL'

#!/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 

兩個 '打印' 和 '進口' 的語言結構。爲什麼'eval'限制使用'import'但不限制'print'?

P.S.我正在使用python 2.6

更新:問題不是「爲什麼導入不起作用?」但「爲什麼打印工作?」是否有一些架構限制或其他?

回答

6

__import__方法由import關鍵字調用:python.org

如果你希望能夠導入你需要一個模塊將__import__方法留在內建中:

src = """ 
print '!!!' 
import os 
""" 

obj = compile(src, '', 'exec') 
eval(obj, {'__builtins__': {'__import__':__builtins__.__import__}}) 
+0

問題不是「爲什麼導入不起作用?」但「爲什麼打印工作?」 – Tiendil 2010-10-16 17:04:53

+0

打印成爲python 3k中的一種方法,我敢打賭它不會工作:) – Sacha 2010-10-16 17:05:48

2

在你eval調用import成功建立然而import使得您已經於您的exec不可用內建利用__import__方法。這是爲了工作確定爲什麼你看到

ImportError: __import__ not found 

print不依賴於任何內建的原因。

你可以通過從建宏只是__import__的東西,如:

eval(obj, {'__builtins__' : {'__import__' :__builtins__.__import__}}) 
+0

好的,但爲什麼一個簡單的語句(如在文檔中說:http://docs.python.org/reference/simple_stmts.html)有適當的內置方法,而另一個沒有?這(建築?)解決方案有什麼實際意義嗎? – Tiendil 2010-10-16 17:02:11

+0

'__import__'方法存在,例如,您可以替換它並更改'import'的語義。但是,使用導入鉤子更好。請參閱http://docs.python.org/library/functions.html#__import__在Python 3.x中,'print'已被替換爲'print()'內建方法,因此您將在3中看到與print相同的行爲。 x – mikej 2010-10-16 17:09:08

0

print work因爲您將'exec'指定爲compile函數調用。

0

import調用global/built __import__函數;如果沒有找到,import失敗。

print不依賴任何全局變量來完成它的工作。這就是爲什麼print適用於您的示例,即使您沒有使用可用的__builtins__

相關問題