[英]How do implicit relative imports work in Python?
假設我有以下文件,
pkg/
pkg/__init__.py
pkg/main.py # import string
pkg/string.py # print("Package's string module imported")
現在,如果我運行main.py
,則顯示"Package's string module imported"
。
這是有道理的,並且按照此鏈接中的以下語句運行:
“它將首先在包的目錄中查找”
假設我稍微修改了文件結構(添加了一個核心目錄):
pkg/
pkg/__init__.py
plg/core/__init__.py
pkg/core/main.py # import string
pkg/string.py # print("Package's string module imported")
現在,如果我運行python core/main.py
,它將加載內置的string
模塊。
同樣在第二種情況下,如果必須遵守“ 它將首先在軟件包目錄中查找 ”的語句,是否應該加載本地string.py
因為pkg
是“軟件包目錄”?
我對“包目錄”一詞的理解特別是帶有__init__.py
的文件夾集合的根文件夾。 因此,在這種情況下, pkg是“軟件包目錄”。 它適用於main.py
以及子目錄(如core/main.py
文件,因為它是此“包”的一部分。
這在技術上正確嗎?
PS:代碼段中#
后面的內容是文件的實際內容(無前導空格)。
軟件包是帶有__init__.py
文件的目錄,是的,並且在模塊搜索路徑上找到時作為模塊加載。 因此, 如果父目錄位於模塊搜索路徑中,則 pkg
只是一個包,您可以將其導入並視為包。
但是通過將pkg/core/main.py
文件作為腳本運行 ,Python將pkg/core
目錄添加到了模塊搜索路徑,而不是pkg
的父目錄。 現在,您的模塊搜索路徑上確實有一個__init__.py
文件,但這不是定義包的原因。 您僅具有__main__
模塊,與其他任何組件都沒有包關系,並且您不能依賴隱式相對導入。
您有三種選擇:
不要將包中的文件作為腳本運行。 將腳本文件放在包外部 ,然后根據需要導入腳本。 您可以將其放在pkg
目錄旁邊 ,或者確保首先將pkg
目錄安裝到模塊搜索路徑上已經存在的目錄中,或者通過讓腳本計算要添加到sys.path
的正確路徑。
使用-m
命令行開關可以像運行腳本一樣運行模塊。 如果使用python -m pkg.core
Python將查找__main__.py
文件並將其作為腳本運行。 -m
開關會將當前工作目錄添加到模塊搜索路徑,因此,當您位於正確的工作目錄中時,可以使用該命令,並且一切正常。 或者將軟件包安裝在模塊搜索路徑上已經存在的目錄中。
讓您的腳本將正確的目錄添加到模塊搜索路徑(基於os.path.absolute(__file__)
獲得當前文件的路徑)。 考慮到您的腳本始終被命名為__main__
,並且導入pkg.core.main
會添加另一個獨立的模塊對象; 您將擁有兩個單獨的命名空間。
我也強烈建議不要使用隱式相對導入。 您可以通過添加嵌套的軟件包或具有相同名稱的模塊來輕松地屏蔽頂級模塊和軟件包。 如果您嘗試在pkg
軟件包中使用import time
則會在標准庫time
模塊之前找到pkg/time.py
而是使用顯式相對模塊引用的Python 3模型; from __future__ import absolute_import
添加from __future__ import absolute_import
到所有文件,然后from . import <name>
使用from . import <name>
from . import <name>
來明確指出從何處導入模塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.