基于Python正確讀取資源文件
我們知道,當(dāng)你把一個(gè)資源文件和一個(gè).py文件放在一起的時(shí)候,你可以直接在這個(gè).py文件中,使用文件名讀取它。例如:
with open('test.txt') as f:
content = f.read()
print('文件中的內(nèi)容為:', content)
運(yùn)行效果如下圖所示:

但請(qǐng)注意,這里我是直接運(yùn)行的read.py這個(gè)文件。如果資源文件是存放在一個(gè)包(package)里面,然后我們?cè)谕饷嬲{(diào)用這個(gè)包里面的.py文件會(huì)怎么樣呢?我們?cè)囈辉嚕?/p>

可以看到,現(xiàn)在Python 已經(jīng)找不到這個(gè)文件了。這是因?yàn)?,我們的入口程序?~/get_title文件夾中,而test.txt文件在~/get_title/util文件夾中。因?yàn)槲覀冞\(yùn)行的是main.py,所以 Python 會(huì)在~/get_title文件夾里面尋找test.txt,自然就找不到了。
如果是引用包里面的其他模塊,可以使用相對(duì)路徑。例如引用同一個(gè)包里面名叫sql_util.py里面的conn對(duì)象,我們可以直接寫(xiě)為from .sql_util import conn。但是資源文件不能使用相對(duì)路徑來(lái)讀取,如下圖所示:

有一個(gè)笨辦法,就是獲取當(dāng)前正在運(yùn)行的這一行代碼所在的文件夾,然后拼出資源文件的完整路徑。修改 read.py 文件:
import os
def read_file():
current_folder = os.path.dirname(__file__)
resource_path = os.path.join(current_folder, 'test.txt')
with open(resource_path) as f:
content = f.read()
print('文件中的內(nèi)容為:', content)
運(yùn)行效果如下圖所示:

但這樣寫(xiě)稍顯麻煩。
如果你的 Python 版本不低于3.7,那么你可以使用importlib.resources來(lái)快速讀取資源文件:
from importlib import resources
with resources.open_text('包名', '資源路徑') as f:
content = f.read()
運(yùn)行效果如下圖所示:

如果你讀取的不是文本文件,那么你可以把resources.open_text改成resources.open_binary,從而讀取二進(jìn)制文件。
但需要注意的是,資源文件必須放在包的根目錄。這樣才能正確讀取。如果資源文件在包內(nèi)部的子目錄中,importlib.resources是不能直接讀取的。
例如我們的包為util,里面有一個(gè)文件夾叫做deep_folder,資源文件test.txt放在deep_folder中,此時(shí),我們?nèi)绻x取這個(gè)資源文件,就必須把在deep_folder文件夾中創(chuàng)建一個(gè)init.py,把它也變成一個(gè)包。然后修改read.py的代碼:
from importlib import resources
from . import deep_folder
def read_file():
with resources.open_text(deep_folder, 'test.txt') as f:
content = f.read()
print('文件中的內(nèi)容為:', content)
把deep_folder作為一個(gè) module 導(dǎo)入,然后把這個(gè) module 作為resources.open_text的第一個(gè)參數(shù)。這樣才能正確讀取,如下圖所示:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python中not not x 與bool(x) 的區(qū)別
這篇文章主要介紹了python中not not x 與 bool(x) 的區(qū)別,我們就來(lái)做一個(gè)選擇,就是 not not x 和 bool(x) 用哪個(gè)比較好?下面一起進(jìn)入文章看看吧2021-12-12
快速解決Django關(guān)閉Debug模式無(wú)法加載media圖片與static靜態(tài)文件
這篇文章主要介紹了快速解決Django關(guān)閉Debug模式無(wú)法加載media圖片與static靜態(tài)文件的操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
Python中集合的內(nèi)建函數(shù)和內(nèi)建方法學(xué)習(xí)教程
這篇文章主要介紹了Python中集合的內(nèi)建函數(shù)和內(nèi)建方法學(xué)習(xí)教程,包括工廠函數(shù)和僅用于可變集合的方法等知識(shí)點(diǎn),需要的朋友可以參考下2015-08-08
python實(shí)戰(zhàn)教程之OCR文字識(shí)別方法匯總
ocr是一種光學(xué)字符識(shí)別技術(shù),簡(jiǎn)單來(lái)說(shuō)它能夠識(shí)別出圖像中的文字并且將其給取出來(lái),下面這篇文章主要給大家介紹了關(guān)于python實(shí)戰(zhàn)教程之OCR文字識(shí)別方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05
Python隨機(jī)數(shù)種子(random seed)的設(shè)置小結(jié)
隨機(jī)數(shù)種子是控制偽隨機(jī)數(shù)生成器的初始值,通過(guò)設(shè)置相同的種子,可以確保隨機(jī)數(shù)序列的一致性,本文主要介紹了Python隨機(jī)數(shù)種子(random seed)的設(shè)置,感興趣的可以了解一下2025-03-03
Python 實(shí)現(xiàn) WebSocket 通信的過(guò)程詳解
WebSocket是一種在Web應(yīng)用程序中實(shí)現(xiàn)雙向通信的協(xié)議,與傳統(tǒng)的HTTP請(qǐng)求-響應(yīng)模型不同,WebSocket允許服務(wù)器主動(dòng)向客戶(hù)端推送數(shù)據(jù),實(shí)現(xiàn)實(shí)時(shí)性和互動(dòng)性,這篇文章主要介紹了Python 實(shí)現(xiàn) WebSocket 通信的過(guò)程詳解,需要的朋友可以參考下2024-06-06
在import scipy.misc 后找不到 imsave的解決方案
這篇文章主要介紹了在import scipy.misc 后找不到 imsave的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05

