簡體   English   中英

Python 函數導入在使用 Spyder 的 Django 中不起作用

[英]Python function import not working in Django using Spyder

我的 Django 項目具有以下文件夾結構,其中controllers是我保存所有自定義.py文件的地方:

C:.
│   db.sqlite3
│   manage.py
│
├───myApp
│   │   admin.py
│   │   apps.py
│   │   forms.py
│   │   models.py
│   │   tests.py
│   │   urls.py
│   │   views.py
│   │   widgets.py
│   │   __init__.py
│   │
│   ├───controllers
│   │   │   helpers.py
│   │   │   function.py
│   │   │   __init__.py
│   │   │

controllers/function.py我想導入文件helpers.py

場景 1:如果我輸入from .helpers import foo並在 Django 中運行它,那么我可以導入 helpers.py,但是如果我在 Spyder 中運行相同的導入,那么我得到: ImportError: attempted relative import with no known parent package

場景 2:如果我輸入from helpers import foo (沒有“點”)並在 Django 中運行它,那么我得到: ModuleNotFoundError: No module named 'helpers' but it works in Spyder!

我在這里缺少什么路徑(或相對路徑)。 我需要能夠在 Django 和 Spyder 中運行一個 python 腳本,而不必刪除. 到處。

問:“如果我在 Spyder 中運行相同的導入”=> 你的意思是在 spyder 的集成 python shell 中嗎? 答:“正確”

那么就值得期待了。

在functions.py 模塊中,您可以使用相對導入(這實際上是您想要的),因為它將相對於當前模塊(“functions.py”)進行解析。

當您在交互式 shell 中時,您不在包中的模塊中,因此相對導入不能在這里工作,您必須使用絕對導入(或相對於當前工作目錄的導入,這應該是成為你sys.path第一個——當然除非有東西(IDE 或其他)弄亂了它。

愛荷華州:

  • 在您的模塊中,保持顯式相對導入(它應該始終有效並解析為正確的“助手”模塊或子包)
  • 在您的 shell 中,使用與您當前的sys.path匹配的限定路徑

編輯

我不完全理解“顯式相對導入”和“限定路徑”的意思

“顯式相對導入”: from .helpers import foo - 它是相對導入(相對於functions模塊),並且是顯式的(顯式使用的語法意味着“在與我和我相同的包中查找‘helpers’模塊或子包在同一級別")

“合格的路徑”:嗯,是的,我猜不是最好的公式。 我的意思是使用從包頂部到模塊的完整 python 限定路徑的“或多或少絕對”導入。 關鍵是什么構成“您的包的頂部”取決於您的sys.path ,而這又可能(或不,取決於幾個因素)取決於您當前的工作目錄。

默認情況下,python 在sys.path第一個位置插入當前目錄。 然后它使用sys.path來查找模塊或包(警告: sys.path列出的路徑不應是包的完整路徑,而是包含包的目錄的路徑)。

IOW,如果你打開一個終端,cd 到你的 django 的項目根目錄並啟動一個(標准)python shell,你的項目的根將在sys.path在第一位,你的helpers模塊的限定名稱將是myapps.controllers.helpers 但是,如果您在myapps那么完整路徑將是controllers.helpers ...

唯一明智的方法實際上是確保您的sys.path永遠不會直接包含任何項目的包路徑(IOW 始終從項目的根目錄運行您的代碼)。 這不僅解決了那些討厭的導入問題,還避免了臭名昭著的“雙重導入陷阱”

“在functions.py 模塊中,您可以使用相對導入”。 你的意思是我可以使用 .?

是的。 實際上,您甚至應該使用它,除非您有令人信服的理由不使用它,因為它會防止在您的sys.path之前出現的另一個同名模塊對helpers模塊的潛在影響 - 並且它非常明確地說明了哪個helpers模塊或您要從中導入的包。

這就是我在場景 1 中所做的,它在 Spyder 中不起作用。

正如我在評論已經mentionned,“確實在Spyder的不工作”是不夠的,說不清楚什么是錯的,因為我們不知道自己在做什么是“不以Spyder的工作” -也沒有確切的錯誤信息和完整的回溯 FWIW,這兩者通常都是“不起作用”問題所必需的(當然,除非問題很明顯)。

但是如果它(正如我所理解的)“在 Spyder 中啟動一個 python shell 並from . helpers import xxx ”那么它確實不會“工作” - 你只能在模塊代碼中使用這種語法,並且模塊必須是一部分一個包,並且包含這個包的目錄必須在你的sys.path

這就是為什么在 python shell 中,您必須使用絕對導入(“from xxx import yyy”)。 但是,哪個確切路徑取決於您的sys.path - 這部分取決於您當前的工作目錄(至少對於普通的 Python shell - 我不使用 Spyder,所以我不知道它在您背后做什么)。

現在,如果 Spyder 不是完全腦殘,它應該使用 django 項目的根作為sys.path第一個元素(或者至少在sys.path有這個目錄),所以完整的限定路徑( from myapp.controllers.helpers import foo應該工作。 如果沒有,請檢查您的 cwd( os.getcwd() )和您的sys.path ,並使用以下內容編輯您的問題:

  • 究竟是做什么的完整描述
  • 確切的錯誤消息和完整的回溯
  • 你的 cwd 和 sys.path

此外,您可能想閱讀一些關於 Python 導入系統的文檔——公平地說,有時它可能是一個特大號的 PITA。

一個 Try except 子句應該這樣做:

try:
    from .helpers import foo
except ImportError:
    from helpers import foo

暫無
暫無

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

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