2012-06-29 77 views
2

Python允許走樣進口,通過import語句...as <ALIAS>條款,像這樣:__import__從哪裏獲取別名?

import mymodule as somealias 
from myothermodule import spam as spamalias, ham as hamalias 

現在,在默認情況下,至少,import語句,包括那些有as -clauses像那些上面,導致致電__builtin__.__import__其參數列表做而不是包括這些別名的名稱。 IOW,AFAICT,下面的「無混疊」 import語句產生對__builtin__.__import__相同的呼叫因爲這樣做上面引述的import語句:

import mymodule 
from myothermodule import spam, ham 

那麼,如何做這些別名進入導入過程? Python是否提供了自定義導入過程如何使用別名的方法?

(我沒有考慮任何特定的應用程序,我只是想更好地瞭解Python中是如何工作的。)

回答

11

功能__import__()在呼叫範圍內不綁定任何名字。基本上,

import foo 

類似於

foo = __import__("foo") 

import foo as bar 

類似於

bar = __import__("foo") 

名稱結合發生在呼叫範圍內,而不是在函數內部,所以__import__()不需要需要知道該模塊將最終綁定到什麼名稱。

這也可以從這些語句的CPython的字節代碼所示:

>>> dis.dis(compile("import foo", "", "exec")) 
    1   0 LOAD_CONST    0 (-1) 
       3 LOAD_CONST    1 (None) 
       6 IMPORT_NAME    0 (foo) 
       9 STORE_NAME    0 (foo) 
      12 LOAD_CONST    1 (None) 
      15 RETURN_VALUE   
>>> dis.dis(compile("import foo as bar", "", "exec")) 
    1   0 LOAD_CONST    0 (-1) 
       3 LOAD_CONST    1 (None) 
       6 IMPORT_NAME    0 (foo) 
       9 STORE_NAME    1 (bar) 
      12 LOAD_CONST    1 (None) 
      15 RETURN_VALUE   

IMPORT_NAME操作碼隱式調用__import__()和葉內部堆棧上生成的模塊。隨後STORE_NAME從堆棧彈出模塊並將其綁定到本地名稱。你可以看到兩個片段之間唯一的區別是模塊被存儲到哪個名稱。

+1

偉大的答案,閃電般快速。我會盡快接受它。謝謝! – kjo