1. 程式人生 > >Python包的相對匯入問題

Python包的相對匯入問題

python指令碼的package相對匯入時,常見兩種寫法:
from . import XXX
from .. import XXX
但有時會出現這樣的錯誤:
SystemError: Parent module '' not loaded, cannot perform relative import
ValueError: attempted relative import beyond top-level package
二者的問題是一樣的,都是目錄被視為package時的解釋錯誤。

相對匯入時,package所對應的資料夾必須正確的被python直譯器視作package,而不是普通資料夾。否則由於不被視作package,無法利用package之間的巢狀關係實現python中包的相對匯入。

資料夾被python直譯器視作package需要滿足兩個條件:

  1. 該資料夾中必須有__init__.py檔案,它可以為空,但必須存在
  2. 該資料夾不能作為頂層模組來執行資料夾中的py檔案 (即不能作為主函式的入口)

附:在from YY import XX中,無論是XX還是YY,只要被python直譯器視作package(資料夾or指令碼檔案都可成為package),就會首先呼叫該package的__init__.py檔案。如果都是package,則呼叫順序是YY,XX。

舉例說明:
目錄樹

test/
 --__init__.py
 --main.py : from . import module
 --main1.py : from sub1 import sub11
 --main2.py : from sub1 import sub13
 --main3.py : from sub2 import sub21
 --module.py
 --sub1/
   --__init__.py : 
   --sub11.py : from . import sub12
   --sub13.py : from .. import sub21
   --sub12.py
 --sub2/
   --sub21.py

[[email protected] test]$python3 main.py 報錯,違反條件2,test不能被視為package,module無法匯入
[[email protected] test]$python3 main1.py 正確,sub1和sub11都是package
[[email protected] test]$python3 main2.py 報錯,違反條件2,sub1和sub13是package,但因為test不是package,sub21無法匯入
[[email protected] test]$python3 main3.py 報錯,違反條件1

,sub2不是package

[[email protected] sub1]$python3 sub11.py 報錯,sub1不能被視為package,sub12無法匯入
[[email protected] sub1]$python3 sub13.py 報錯,sub1和test都不是package

一種方法是更改目錄樹:

parent/
	--main.py : from test import module
	--main2.py : from test.sub1 import sub13
	--main3.py : from test.sub2 import sub21
	--test/
		--__init__.py
	 	--main1.py : from sub1 import sub11
	 	--module.py
		--sub1/
	 		--__init__.py : 
	 		--sub11.py : from . import sub12
	 		--sub13.py : from .. import sub21
	 		--sub12.py
		--sub2/
			--__init__.py : 
	 		--sub21.py

在parent目錄下前4條能執行,後2條在test目錄下能執行。

另一種方法是利用python的-m引數:
[[email protected] test]$python3 -m main