[英]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 或其他)弄亂了它。
愛荷華州:
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
,並使用以下內容編輯您的問題:
此外,您可能想閱讀一些關於 Python 導入系統的文檔——公平地說,有時它可能是一個特大號的 PITA。
一個 Try except 子句應該這樣做:
try:
from .helpers import foo
except ImportError:
from helpers import foo
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.