2017-09-14 130 views
1

我有這樣的代碼導入錯誤:不能兩個文件之間導入名導入相同

mainModule

from src.comp.mypackage.wait import Wait 
from src.comp.mypackage.men import Men, MenItem 

""" Code and stuff using Men and MenItem """ 

if __name__ == '__main__': 
    MenuTestDrive.main() 

男人

from abc import ABCMeta, abstractmethod 
from src.comp.mypackage.util import NullUtil, CompUtil 

UTIL

from src.comp.mypackage.stack import Stack 
from src.comp.mypackage.men import Men 

""" Code and stuff using Men and MenItem """ 

和運行mainModule時,我正在給這個錯誤:

Traceback (most recent call last): 
    File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/mainModule.py", line 2, in <module> 
    from pythonDesignPatterns.src.comp.mypackage.men import Men, MenItem 
    File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/men.py", line 2, in <module> 
    from pythonDesignPatterns.src.comp.mypackage.iterator import NullUtil, CompUtil 
    File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/util.py", line 2, in <module> 
    from pythonDesignPatterns.src.comp.mypackage.men import Men 

ImportError: cannot import name 'Men' 

我使用pyCharm,但錯誤在命令行是一樣的。

我可以提供更多的代碼,但我不認爲有任何使用類的幻想,只會分散注意力。

我應該在哪裏尋找失敗?

+0

名字'男人'真的存在'男人'包?你能否在你的問題中提供它的定義? – Grigoriy

回答

2

TL; DR:蟒蛇不允許圓形進口,所以你不能有模塊men從模塊util進口,如果模塊util進口模塊men

較長的答案:

你要明白,在Python importclassdef等其實都是可執行語句和一切(或幾乎)發生在運行時。在給定進程中首次導入模塊時,所有頂級語句都將按順序執行,將創建一個module實例對象,並將所有頂級名稱作爲屬性(請注意,classdefimport都綁定了名稱)並插入到sys.modules緩存字典中,以便相同模塊的下一個導入將直接從緩存中檢索。

在你的情況下,首先導入時,該men模塊試圖導入util模塊,這是不是在sys.modules卻又如此Python運行時所處的util.py(或.pyc文件)文件並執行它。然後它到達from src.comp.mypackage.men import Men。此時,men.py尚未完全執行,因此沒有Men屬性。

規範的解決方案是將循環依賴提取到第三個模塊中,或者將兩個模塊合併爲一個模塊,具體取決於一個對您的具體情況有意義的事情(目標是一如既往地讓模塊具有低耦合和高凝聚力)。 FWIW,即使語言支持它們,循環依賴也被認爲是不好的設計。

有時(大多數情況下,在複雜的框架中,將某些特定結構強加給您的代碼和特定的導入順序),最終可能會出現循環依賴鏈或者更復雜(如A.funcX依賴於By,B取決於依賴於D的C,它依賴於最終依賴於A.funcZ的E)和/或非常難以以有意義的方式乾淨地重構。作爲最後的手段,您仍然可以在函數中推遲一些導入語句(在上面它將在A.funcX之內)。這是仍然認爲是一種不好的做法,應該只能作爲最後的手段使用。

作爲便箋:從您的軟件包命名方案我可以聞到強大的Java影響力。 Python不是Java!不是說Java有什麼問題,它只是these are two wildly different languageswildly different designs, idioms and philosopies

試圖在Python中強制使用Java習語和習慣最好是在痛苦和沮喪的經歷(這裏已經完成了......),所以我的建議是:忘記你學習Java的大部分內容,開始學習Python(而不僅僅是語法 - 語法實際上只是語言的一部分,不一定是最重要的語法)。在Python中,我們傾向於平面嵌套,並且不要嘗試爲每個類使用一個模塊,您可以在一個模塊中包含整個(微)框架,如果沒有實際的理由將其分解爲子模塊,那也沒關係。

+0

這是一個從Java翻譯而來的設計模式源代碼,但總的來說,我將模型類似的對象分組,並且在它們不配合任何對象(如Java接口)等時合併對象。但是對於這些模式,一些Java設計依賴於。無論如何感謝您的建議,這是一個很好的建議 – madtyn