2011-08-19 40 views
9

如果我導入模塊,則模塊名稱將顯示在sys.modulesglobals()之間。如果我再次刪除它,它將從globals()中刪除,但仍位於sys.modules。爲什麼這樣?sys.modules和globals中的模塊名稱()

import mymodule 
'mymodule' in globals() # True 
'mymodule' in sys.modules # True 
del mymodule 
'mymodule' in globals() # False 
'mymodule' in sys.modules # Still True, why? 

我還發現了以下區別:

from mypackage import mymodule 
'mypackage' in sys.modules   # True 
'mymodule' in sys.modules   # False ! 
'mypackage.mymodule' in sys.modules # also True ! 

而答案是互補的爲globals()

'mypackage' in sys.modules   # False 
'mymodule' in sys.modules   # True 
'mypackage.mymodule' in sys.modules # False 
+0

它*是*可能從sys.modules,'del sys.modules ['mymodule']'中刪除模塊,這有時很有用。 – SingleNegationElimination

回答

4

就像任何其他Python對象一樣,模塊會一直存在,直到沒有更多的引用爲止。換句話說,sys.modules的行爲像一個普通的字典,並

import mymodule 
lst = {mymodule.__name__: mymodule} 
'mymodule' in globals() # True 
'mymodule' in lst   # True 
del mymodule 
'mymodule' in globals() # False 
'mymodule' in lst   # Still True 

sys.modules只徵詢import語句。您可以從sys.modules中刪除一個模塊,以使Python在下次導入時重新加載它。

3

因爲Python在sys.modules緩存模塊,以防止(昂貴的,慢)正在運行的模塊尋找過程超過了必要的範圍。

如果需要,可以從sys.modules刪除模塊,但reload也可以。


更詳細地說,當你import mymodule各種事情發生。關閉我的頭頂,並假設mymodule不內置於解釋器可執行模塊之一:

  1. 的解釋程序運行一些複雜的代碼,以找到包含mymodule文件(這可能是mymodule.pymymodule.pyc ,或mymodule.pyd - 或者其他的東西,我沒有想到,這通過當前目錄,sys.path,以及其他地方看起來

  2. 因此找到的文件是lexed,解析和編譯如果有必要的話)解釋器字節碼。

  3. 編譯模塊被執行,給出一個模塊對象。

  4. 模塊對象被插入到sys.modules中。

  5. 模塊對象綁定到import語句中指定的局部變量。

(以上是一個非常粗略的估計基於我記得背後import的機制。這是一個在重要和微妙的方式可能是錯誤的。)

注意,那麼,結合模塊對象本地名稱實際上只是實際導入過程中的一小部分。通過執行del mymodule刪除名稱綁定不會影響導入的其餘部分。

+1

但是,如果我通過執行'del mymodule'來刪除名稱綁定,我將它從命名空間中刪除,以便我可以執行'import mymodule',這兩個步驟一起等同於執行'reload(mymodule)',對吧? – HongboZhu

+1

@洪波:錯誤:'import'在sys.modules'中查找是否已經導入模塊。如果有,它只會給你它上次導入模塊時所做的模塊對象。由於'del mymodule'不會將模塊對象從'sys.modules'中刪除,重新導入它只會將名稱重新綁定到'sys.modules'中的對象。 – katrielalex

+1

@Hongbo:如果你想重新導入模塊,請執行'reload(module)'。等同地,從'sys.modules'中刪除它,然後'導入'它。 – katrielalex

4

del刪除適當範圍內名稱的綁定;它與模塊本身無關。

sys.modules保留所有已加載模塊的列表,而不管它們是否綁定到程序中的任何名稱。