絕對路徑導入格式爲import a.b
或者from a import b
,相對路徑導入格式爲from . import b
或者from ..a import b
。python
python2默認爲相對路徑導入,python3默認爲絕對路徑導入。git
爲使python2,3通用,建議採用相對路徑導入from .a import b
github
一個目錄存在__init__.py
文件,則該目錄成爲一個包。shell
包中的一個模塊能夠採用相對路徑導入包,不影響模塊功能;一個py腳本(未成爲模塊,即其目錄及父目錄內無__init__.py
)能夠採用相對路徑導入包,並以腳本模式運行。但包含相對導入的模塊,不能直接以腳本模式運行,常見報錯爲:app
# python2 Traceback (most recent call last): File "module_x.py", line 1, in <module> from . module_y import spam as ham ValueError: Attempted relative import in non-package # python3 Traceback (most recent call last): File "module_x.py", line 1, in <module> from . module_y import spam as ham SystemError: Parent module '' not loaded, cannot perform relative import
創建示例文件結構以下:
注:以/
結尾的爲文件夾。spa
/home/zhkai/ mobike/ __init__.py utils.py data_process/ loc.py
注意此時mobike成爲一個python包。
在loc.py
中導入utils.py
該怎麼辦?code
在loc.py
中導入util
的方法爲:orm
import sys sys.path.append('/home/zhkai') from mobike.utils import read_csv
須要注意,這裏導入系統路徑的是mobike所在目錄的路徑,路徑自己不包含mobike。
此時utils
就像自帶的python包同樣,loc.py
可直接運行。ip
python的man page裏有這個參數:get
-m module-name Searches sys.path for the named module and runs the corresponding .py file as a script.
因此能夠在不修改模塊代碼文件的狀況下:
代碼文件仍爲相對路徑:
from ..utils import read_csv
切換到mobike包同級目錄下執行:
☁ ~ python3 -m mobike.data_process.loc
注意:此時若loc.py代碼中有其餘相對路徑,此時的相對路徑是基於shell命令所在位置,即
~
的,可能會形成錯誤。import語句中的相對路徑,還是基於文件所在位置,故不影響。
推薦這種方法,由於無需修改代碼文件。
還有句話不太理解:若是一個模塊被直接運行,則它本身爲頂層模塊,不存在層次結構,因此找不到其餘的相對路徑。