2010-07-13 61 views
1

我有一系列python模塊寫在同一個目錄下,我遇到了ImportError問題。當我嘗試'重新導入'模塊時,爲什麼會遇到ImportError?

我使用的三個模塊是draw_menu.py,errors.pyfile_operations.py

errors.py我需要的錯誤代碼的列表,我使用在file_operations.py定義的自定義方法以打開包含代碼因此我使用import file_operations只是她爆炸的下方(在類定義如上)的文件。

file_operations.py我使用error.py中定義的方法在出錯時打印錯誤消息(例如找不到文件等)。因此我在這裏採用相同的方式import errors

上述工作正常,但當我使用draw_menu.py,它使用文件來定義ascii菜單中的選項(因此我使用import file_operations)時遇到了一個ImportError。

ImportError: cannot import name file_operations

我明白,這是因爲 '進口樹' 如果你喜歡流向如下:

draw_menu < - file_operations < - errors < - file_operations

這是每個重要模塊可以單獨使用,爲什麼這是一個問題,我怎樣才能克服這一點,而不需要從errors.py刪除import file_operations

三江源

湯姆

回答

2

圓形進口可能在Python引起的問題(如你所期望的)。這也許值得一試,如果:?

A)errors.py和file_operation.py應該是單個模塊(如果他們都如此依賴對方,做他們需要的是獨立的)

B)你可以在一個或另一個模塊中延遲import。在函數調用之前,函數中的導入語句不會運行,雖然在模塊的開頭導入通常是很好的做法,但在Python中不需要。在這種情況下,它可以避免導入期間的循環引用。

+0

感謝您的快速回復,我保留了兩個模塊,並將'import file_operations'移入'errors.py'中定義的所需方法內,這解決了我的問題。通常從循環導入中會產生什麼樣的問題? – Thorsley 2010-07-13 09:29:36

+0

@Thorsley:http://stackoverflow.com/questions/3082015/python-module-initialization-order/3082097#3082097 – 2010-07-13 09:31:16

+0

在http://effbot.org/zone/上有一篇關於python導入的舊文章,但非常好。 import-confusion.htm和關於循環進口的章節。值得一讀。 – mavnn 2010-07-13 09:31:30

1

問題不是進口本身,而是依賴關係file_operations只有在導入errors後才能被處理,但errors只有在導入了file_operations之後才能被處理。 Python認識到這是一種不可能的情況,併產生錯誤。

對此的最佳解決方案是重構您的文件,以便您不再需要此循環依賴項。如果這是不可能的,另一種解決方案是更改其中一個模塊,以便在需要它的函數內發生違規導入,而不是在頂層。這意味着模塊的初始處理不依賴於導入,因此它會成功。

+0

這是不正確的。其他模塊中的引用不能*使用*直到導入過程完成足夠遠以便定義它們,而僅僅導入模塊不是問題。 – 2010-07-13 09:27:37

0

除了打破循環依賴,您可以嘗試移動導入調用的位置。不要忘記,Python中的導入只是常規語句,因此您可以導入內部函數。

問題是導入(作爲副作用)將實際運行正在導入的模塊(第一次調用導入時)。所以,如果你正在導入一個導入原始模塊的模塊,那麼你會感到困惑。

您可能會發現,只需在實際需要使用它的位置導入錯誤/ file_operations即可緩解此問題。這可能在一個函數中。因此,也許將錯誤的調用包含到函數中:

 

def print_error_message(err): 
    from errors import print_error_message as _print_error_message 
    _print_error_message(err) 
 

這樣,您只會在正常導入運行後導入錯誤。

+0

或者你可以只在頂部輸入錯誤,並在函數內部使用'errors.print_error_message'。 – 2010-07-13 09:30:02

相關問題