python如何使用import引入其他目錄文件或自定義模塊
問題描述
在python工程中,常常需要使用import引入自己編寫的其他模塊,但其它模塊有時不在同一個文件夾下。
此時直接import會導(dǎo)致找不到包而報錯
ModuleNotFoundError: No module named '****'
下面提供2種解決方案。
解決方案
以下面的項(xiàng)目結(jié)構(gòu)為例進(jìn)行說明。

方案1:使用相對路徑(局限)
在import時直接使用相對路徑
.代表當(dāng)前文件所在路徑..代表當(dāng)前文件的父目錄...代表爺爺目錄,以此類推,每多一個點(diǎn),就向上翻一層目錄。
例1,在f1.py中寫:
from ..p2 import f2.py
例2,在t1.py中寫:
from ..b import t2.py
這樣寫能否執(zhí)行成功,取決于主函數(shù)入口(即你執(zhí)行的文件)!記住這個原則(局限):
相對路徑所涉及的目錄范圍內(nèi)不允許有主函數(shù)入口
不滿足這個原則時,報錯
ValueError: attempted relative import beyond top-level package
在上面的項(xiàng)目結(jié)構(gòu)中,如果我們執(zhí)行python main.py,那么在main.py中引入t1.py會報錯,
原因是t1.py中使用相對引入時,..回退到的目錄是項(xiàng)目主目錄,也就是main.py所在的目錄,違反了該原則。
但在main.py中引入f1.py是正確的,因?yàn)?code>f1.py在使用相對路徑引入時最多回退到pkg文件夾,不會影響main.py的執(zhí)行。
方案2:絕對路徑引入(推薦)
1. 在main.py中調(diào)用t1.py
這個很常規(guī),直接在main.py使用import即可
form a.t1 import *
2. 在t1.py中調(diào)用main.py
在t1.py中寫:
import sys from pathlib import Path sys.path.append(str(Path(__file__).resolve().parents[1])) # 將父級目錄加入執(zhí)行目錄列表 from main import * # 由于main.py所在目錄已加入到sys.path,可直接引入
代碼中parents返回一個列表,parents[0]代表該文件所在目錄,下標(biāo)每加一,目錄向上一層,所以這里parents[1]得到的是父目錄。
3. 幾個坑
1. os.getcwd()
- 這個函數(shù)獲取的始終是當(dāng)前終端所在目錄。
- 例如我的終端現(xiàn)在處在
/home/code/下,執(zhí)行python a/1.py,文件1.py中的語句os.getcwd()返回值為/home/code/。
2. __file__
- 當(dāng)前文件相對于終端的路徑。
- 例如我的終端現(xiàn)在處在
/home/code/下,執(zhí)行python a/1.py,文件1.py中的語句__file__返回值為a/1.py。 - 使用
os.path.abspath(__file__)可獲得該文件的絕對路徑/home/code/a/1.py。 - Tips:拼接路徑
os.getcwd()/__file__就是該文件的完整絕對路徑。
3. sys.path[0]
- 直接運(yùn)行py文件,即
python xxx.py時,為執(zhí)行文件所在的絕對目錄(不管終端處于什么路徑)。 - 需要注意,若執(zhí)行
python 1.py,而1.py中又import了其他目錄的2.py,那么2.py的sys.path[0]與1.py中相等,也就是說在import其他文件時,其他文件的sys.path[0]將以當(dāng)前被執(zhí)行的文件為準(zhǔn)。 - 以模塊運(yùn)行時,即
python -m xxx時,為終端所在絕對目錄,等于os.getcwd()。
4. 小結(jié)
- 在
.py文件中,使用__file__最保險。 - 但是在
.ipynb文件中不存在__file__變量,怎么辦? - 由于
.ipynb文件一般不考慮被其他文件import,因此直接使用sys.path[0]取得文件所在目錄即可。
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
pandas實(shí)現(xiàn)將日期轉(zhuǎn)換成timestamp
今天小編就為大家分享一篇pandas實(shí)現(xiàn)將日期轉(zhuǎn)換成timestamp,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12
python實(shí)現(xiàn)域名系統(tǒng)(DNS)正向查詢的方法
這篇文章主要介紹了python實(shí)現(xiàn)域名系統(tǒng)(DNS)正向查詢的方法,結(jié)合實(shí)例形式分析了Python使用socket模塊下getaddrinfo方法進(jìn)行域名查詢的具體技巧,需要的朋友可以參考下2016-04-04
Python如何利用pandas讀取csv數(shù)據(jù)并繪圖
這篇文章主要介紹了Python如何利用pandas讀取csv數(shù)據(jù)并繪圖,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
小結(jié)Python用fork來創(chuàng)建子進(jìn)程注意事項(xiàng)
今天看到別人的源代碼中有 fork 子進(jìn)程來操作數(shù)據(jù)。但是由于 fork 之后,沒有及時的退出,導(dǎo)致系統(tǒng)中的Python進(jìn)程越來越多,子進(jìn)程越來越多了。2014-07-07
Python實(shí)現(xiàn)Windows和Linux之間互相傳輸文件(文件夾)的方法
下面小編就為大家?guī)硪黄狿ython實(shí)現(xiàn)Windows和Linux之間互相傳輸文件(文件夾)的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05
python結(jié)合QT實(shí)現(xiàn)簡單的圖書管理系統(tǒng)
這篇文章主要介紹了一個基于Python和PyQt5的圖書管理系統(tǒng)開發(fā)教程,適合Python初學(xué)者學(xué)習(xí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2026-02-02

