簡體   English   中英

從終端運行腳本時出現 ModuleNotFoundError

[英]ModuleNotFoundError when running script from Terminal

我有以下文件夾結構:

  • app
    • __init__.py
    • utils
      • __init__.py
      • transform.py
    • products
      • __init__.py
      • fish.py

在 fish.py 中,我按如下方式導入transformimport utils.transform

當我從 Pycharm 運行 fish.py 時,它運行得非常好。 但是,當我從終端運行 fish.py 時,出現錯誤ModuleNotFoundError: No module named 'utils'

我在終端中使用的命令:來自 app 文件夾python products/fish.py

我已經研究過這里建議的解決方案: 從不同文件夾導入文件,將應用程序文件夾的路徑添加到sys.path幫助中。 但是我想知道是否有任何其他方法可以使其工作而無需在fish.py添加兩行代碼。 是因為我/products目錄下有很多腳本,不想每一個都加兩行代碼。

我查看了一些開源項目,我看到了許多從並行文件夾導入模塊而不向 sys.path 添加任何內容的示例,例如: https : //github.com/jakubroztocil/httpie/blob/master/httpie/plugins /builtin.py#L5

如何讓它以同樣的方式適用於我的項目?

您可能想要運行python -m products.fish 它和python products/fish.py的區別在於,前者大致相當於在 shell 中執行import products.fish (但__name__設置為__main__ ),而后者不知道它在包層次結構中的位置.

這擴展了@Mad Physicist 的回答。


首先,假設app本身是一個包(因為你向它添加了__init__.py )並且utilsproducts是它的子包,你應該將導入更改為import app.utils.transform ,並從根目錄(其父目錄)運行 Python app )。 本答案的其余部分假設您已完成此操作。 (如果您不打算將app作為根包,請在評論中告訴我。)


問題是您正在運行app.products.fish就好像它是一個腳本一樣, app.products.fish文件的完整路徑提供給python命令:

python app/products/fish.py

這使得 Python 認為這個fish.py文件是一個獨立的腳本,不屬於任何包的一部分。 如文檔中所定義(參見此處,在<script> ),這意味着 Python 將在與腳本相同的目錄中搜索模塊,即app/products/

如果腳本名稱直接引用 Python 文件,則將包含該文件的目錄添加到sys.path的開頭,並且該文件作為__main__模塊執行。

但當然, app文件夾不在app/products/ ,因此如果您嘗試導入app或任何子包(例如app.utils ),它將引發錯誤。

啟動作為包一部分的腳本的正確方法是使用-m (模塊)開關參考),它將模塊路徑作為參數並將該模塊作為腳本執行(但保持當前工作目錄為模塊搜索路徑):

如果給出此選項,[...] 當前目錄將被添加到sys.path的開頭。

因此,您應該使用以下內容來啟動您的程序:

python -m app.products.fish

現在,當app.products.fish嘗試導入app.utils.transform模塊時,它將在您當前的工作目錄(其中包含app/...樹)中搜索app並成功。


作為個人建議:不要將可運行的腳本放在包中 僅使用包來存儲所有邏輯和功能(函數、類、常量等),並編寫一個單獨的腳本來根據需要運行您的應用程序,將其放在之外 這將使您免於此類問題(包括雙重導入陷阱),並且還有一個優勢,您可以通過為每個包編寫單獨的啟動腳本來為同一個包編寫多個運行配置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM