2009-11-28 175 views
18

我有周期性的導入問題,將一些新代碼添加到一個非常大的應用程序中,我試圖確定哪些文件是導致此問題的最可能原因。有沒有辦法跟蹤哪些文件導入哪些文件?我查了一下,發現了python trace命令,但它只是在主python庫中顯示了一堆活動。如何跟蹤python導入

我基本上尋找一個應用程序,會告訴我是這樣的:

App1 >>imports>> App2,App3.method 
App2 >>imports>> App3,etc 

我可以通過我的所有文件只是看看,但我寧願沒有,這是一個很大的應用程序。

回答

-2

應該不可能在python中獲得循環導入,因爲它會在再次導入之前檢查模塊是否已經導入。無論您調用導入多少次,您都只能導入一次模塊。

http://groups.google.com/group/comp.lang.python/browse_thread/thread/1d80a1c6db2b867c?pli=1

進口相當簡單明瞭 真的。請記住以下內容:

'import'和'from xxx import yyy'是 可執行語句。當正在運行的程序到達 行時,它們執行 。

如果模塊不在sys.modules中, 然後導入創建sys.modules中新模塊 項,然後在模塊中執行 代碼。它不會將 返回到調用模塊 直到執行完成。

如果一個模塊並在sys.modules中 存在,那麼進口僅僅返回 模塊它是否已經完成 執行。這就是爲什麼 循環進口可能會返回模塊 看起來部分是空的。

最後,執行腳本在運行 模塊命名__main__,進口以自己的名義在 腳本將創建 無關 __main__一個新的模塊。

把這個地段放在一起,你 不應該得到任何意外,當 導入模塊。

+6

這是非常有可能得到循環進口。它們不會無限循環,但它們會在需要時未定義函數時產生問題,因爲兩個文件相互導入。 – 2009-11-28 00:22:54

+3

當你從一個模塊中專門導入一個項目,並且另一個模塊導入你時,python中的循環導入只是一個問題。如果你這樣做: 在A.py:進口乙 在B.py:導入 然後,你會不會有問題,即使他們循環導入海誓山盟,因爲引用推遲到進口的實際執行/使用項目。只有當您從另一個模塊請求一個項目(即,在導入時請求一個參考)時,尚未定義這個項目會導致問題。 – 2013-02-23 09:32:19

9

嘗試使用python -v來運行您的程序。它會跟蹤進口的順序。

另一種選擇是pylint,它會提醒您各種問題,包括循環導入。

+3

我想在uwsgi下運行python的時候使用這個-v選項。我最終把這個添加到我的uwsgi ini文件中: 'env = PYTHONVERBOSE = 1' 然後輸出進入正常的uwsgi日誌文件中指定的內容。 – 2011-11-14 23:17:10

14

這裏有一個簡單(略簡陋;-)方式追查「是誰在試圖導入什麼」,在模塊名稱方面:

import inspect 
import __builtin__ 
savimp = __builtin__.__import__ 

def newimp(name, *x): 
    caller = inspect.currentframe().f_back 
    print name, caller.f_globals.get('__name__') 
    return savimp(name, *x) 

__builtin__.__import__ = newimp 

賦予,例如(救以此爲tracimp.py):

$ python -c 'import tracimp; import email; import sys; import email.mime' 
email __main__ 
sys email 
email.mime email 
sys __main__ 
email.mime __main__ 

正如你看到的,「包裝」的__import__內置的一個具體特點是:它不會被一個事實,即模塊被進口的沉默已經在sys.modules:因爲照顧是__import__的工作之一,我們的包裝被稱爲兩個模塊「第一次加載」,因爲它們以前已經導入過,所以它們只會從sys.modules獲取。當您嘗試診斷循環導入時,這應該非常方便(它歸結爲在有向圖中查找循環,其邊界由兩個模塊名稱 - 導入和導入器 - 這種簡單方法在每個模塊上打印輸出線)。