python的相對引用問題

2022-07-15 15:57:08 字數 2978 閱讀 8137

遇到乙個坑,import相對路徑引起的。

我有乙個如下的檔案結構:

test/

__init__.py # 此檔案為空,代表test是乙個package

m1.py

m2.py

m1.py檔案內容如下:

# m1.py

a = 1

我想在m2.py檔案中使用m1的變數,內容如下:

# m2.py

from .m1 import a

b = a + 1

if __name__ == '__main__':

print(b)

此時執行m2.py會報如下錯誤:

itscs-macbook-pro:test itsc$ python m2.py 

traceback (most recent call last):

file "m2.py", line 1, in from .m1 import a

modulenotfounderror: no module named '__main__.m1'; '__main__' is not a package

python可以將檔案以兩種方式執行:

python test/m2.py
python -m test.m2
此處為第一種,執行python m2.py的意思是將m2.py當做指令碼執行。

機制1:

python的模組(module)有乙個__package__屬性,如果這個屬性存在並且有值,相對匯入(import)就會基於這個屬性去匯入,而不是基於__name__屬性,參見pep 0366。使用指令碼方式執行時,__package__屬性值為none,那麼將會基於__name__屬性去做相對匯入;而執行python -m test.m2時,__package__屬性值為模組所在包路徑,此處是:test,此時將通過該test去做相對匯入。

機制2:

每乙個模組都有乙個__name__屬性,它代表了「模組名」,例如此處的m2,當執行python m2.py時:

模組裡的**會被執行,就好像你匯入了模組一樣,但是__name__被賦值為__main__,引。

所以報錯裡面提示的是__main__.m1找不到,而不是__m2__.m1找不到。

以上兩個機制解釋了為什麼報錯。首先,使用指令碼方式執行時__package__屬性值為none,那麼將會基於__name__屬性去做相對匯入,而此時的__name__被賦值為__main__,使用__main__去做相對匯入是會失敗的,應為它和m1並沒有構成相對關係。

附:python文件中有這樣一句解釋:

請注意,相對匯入是基於當前模組的名稱進行匯入的。由於主模組的名稱總是"__main__",因此用作python應用程式主模組的模組必須始終使用絕對匯入。引

根據上面的原因分析,有兩種解決辦法:

1.使用相對路徑,使用帶-m引數方式呼叫。

2.使用絕對路徑,使用絕對路徑就避開了相對路徑那些問題。

將其當做乙個module來執行(執行乙個module需要在package外面執行)(參考):

1.將當前路徑切換到test資料夾的上級目錄目錄(不是test裡面)

2.執行如下命令:

python -m test.m2
注意:首先,多了乙個-m選項;其次,路徑從test資料夾開始寫的,也就是m1和m2的父目錄;最後,m2不帶.py字尾。此時__package__屬性值為test,將通過該test去做相對匯入,就沒問題。

如前所述,相對引用依賴模組名,那麼不使用相對依賴就沒有這個限制,將m2.py檔案內容修改如下:

from m1 import a

b = a + 1

if __name__ == '__main__':

print(b)

相對於之前的版本,只是把m1前面的點號去除了,然後再次執行(目錄切換到test裡面):

itscs-macbook-pro:test itsc$ python m2.py

2

用這個方法的前提是m1這個模組在python的搜尋路徑中是唯一的。如果不唯一,就需要把test資料夾的路徑匯入到pythonpath中。

relative imports in python 3

pep 366 -- main module explicit relative imports

what's the purpose of the 「package」 attribute in python?

命令列與環境

execution of python code with -m option or not

Python 模組相對引用

檔案結構如下 python directory init py init py sub1 init py mod1.py sub2 init py mod2.py除了 mod1.py,其他檔案內容都為空。mod1.py print name format name print package for...

python相對匯入問題 Python 相對匯入

我正在開發乙個python程式,它在其中管理和執行模組 py python檔案 這些模組可以由使用者新增,並可以通過使用import函式匯入到主程式 foo.py 中.這是目錄結構 foo foo.py main script.imports ouput.py,core.py and bar.py ...

git 相對引用

通過雜湊值指定提交記錄很不方便,所以 git 引入了相對引用。使用相對引用的話,你就可以從乙個易於記憶的地方 比如bugfix 分支或 head 開始計算。下面介紹兩個簡單的用法 使用 向上移動 1 個提交記錄 使用 向上移動多個提交記錄,如 3 1.操作符 把這個符號加在引用名稱的後面,表示讓 g...