2016-07-28 114 views
2

我敢肯定,這是一個非常簡單的問題,我只是錯過了一些非常明顯的東西,但是現在這個困境的答案已經讓我幾個小時了。Python的相對導入找不到包

我的項目目錄結構是這樣的:一邊在我的命名慣例,在這裏目錄結構

-PhysicsMaterial 
    -Macros 
     __init__.py 
     Macros.py 
    -Modules 
     __init__.py 
     AvgAccel.py 
     AvgVelocity.py 
    -UnitTests 
     __init__.py 
     AvgAccelUnitTest.py 
     AvgVelocityUnitTest.py 
    __init__.py 

批評,我似乎無法能夠使用相對進口。我試圖相對導入模塊文件中AvgAccelUnitTest.py進行測試:

from .Modules import AvgAccel as accel 

不過,我不斷收到:

ValueError: Attempted relative import in non-package 

因爲我有我的所有初始化文件設立的在我的整個結構中,我也將頂級目錄添加到我的PYTHONPATH中,我很難過。爲什麼python不能解釋包並正確導入文件?

回答

2

發生這種情況是因爲您運行的腳本爲__main__。當你運行一個這樣的腳本:

python /path/to/package/module.py 

該文件被加載爲__main__,而不是package.module,所以它不能做的相對進口,因爲它不是一個包的一部分。

這可能會導致奇怪的錯誤,其中您的腳本中定義的類被定義兩次,一次爲__main__.Class,再次爲package.module.Class,這可能導致isinstance檢查失敗並出現類似的異常情況。正因爲如此,你通常不應該直接運行你的模塊。

對於您的測試,您可以在tests目錄內刪除__init__.py,只使用絕對值而不是相對導入。事實上,你的測試可能根本不應該放在你的軟件包內。

或者,您可以創建一個測試運行器腳本來導入您的測試並運行它們。

+0

@ Brendan Abel謝謝你的信息。在做了更多研究之後,我得出了完全相同的結論:最終,我最終使用了sys.path.append並執行絕對導入。它不應該進一步打擾我,因爲我不打算在目錄中重新定位模塊。這實際上也解決了另一個涉及我需要的函數裝飾器的導入問題,所以這是兩個大拇指! –

+0

如果其他模塊導入您在命令行上運行的相同模塊,則可能仍會遇到問題。 –

+0

我想我會穿過那座橋。到那時我肯定會有更好的解決方案。這只是一個沒有意圖發貨的業餘愛好程序,所以我認爲它會好起來的 –