一日一技:Python讀取包裏面的數據文件的三種方法

一日一技:Python讀取包裏面的數據文件的三種方法ide

一日一技:Python讀取包裏面的數據文件的三種方法

咱們知道,寫Python代碼的時候,若是一個包(package)裏面的一個模塊要導入另外一個模塊,那麼咱們可使用相對導入:函數

假設當前代碼結構以下圖所示:
一日一技:Python讀取包裏面的數據文件的三種方法spa

其中 test_1是一個包,在util.py裏面想導入同一個包裏面的 read.py中的 read函數,那麼代碼能夠寫爲:3d

from .read import read

def util():
    read()

其中的 .read表示當前包目錄下的 read.py文件。此時 read.py文件中的內容以下:code

def read():
    print('閱讀文件')

經過包外面的main.py運行代碼,運行效果以下圖所示:
一日一技:Python讀取包裏面的數據文件的三種方法blog

如今,咱們增長一個數據文件, data.txt,它的內容以下圖所示:
一日一技:Python讀取包裏面的數據文件的三種方法圖片

而且想經過read.py去讀取這個數據文件並打印出來。utf-8

修改read.py,試圖使用相對路徑來打開這個文件:字符串

def read():
    with open('./data.txt', encoding='utf-8') as f:
        text = f.read()
        print(text)

運行代碼發現報錯:
一日一技:Python讀取包裏面的數據文件的三種方法get

這個緣由很簡單,就是若是數據文件的地址寫爲: ./data.txt,那麼Python就會從當前工做區文件夾裏面尋找 data.txt。因爲咱們運行的是 main.py,那麼當前工做區就是 main.py所在的文件夾,而不是 test_1文件夾。因此就會出現找不到文件的狀況。

爲了解決這個問題,咱們有三種解決方式。

  • 使用絕對路徑(代碼公衆號排版可能有問題,以圖片爲準)
def read():
    with open('/Users/kingname/Project/DataFileExample/test_1/data.txt',encoding='utf-8') as f:
        text = f.read()
        print(text)

運行效果以下圖所示:
一日一技:Python讀取包裏面的數據文件的三種方法

先獲取 read.py文件的絕對路徑,再拼接出數據文件的絕對路徑:

import os

def read():
    basepath = os.path.abspath(__file__)
    folder = os.path.dirname(basepath)
    data_path = os.path.join(folder, 'data.txt')
    with open(data_path, encoding='utf-8') as f:
        text = f.read()
        print(text)

運行效果以下圖所示:
一日一技:Python讀取包裏面的數據文件的三種方法

  • 使用pkgutil庫
    import pkgutil

def read():
data_bytes = pkgutil.get_data(package, 'data.txt')
data_str = data_bytes.decode()
print(data_str)

運行效果以下圖所示:
![](https://s4.51cto.com/images/blog/202012/03/587b79f34820b07f4eaf3f8c0c1bd4ce.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

pkgutil是Python自帶的用於包管理相關操做的庫, pkgutil能根據包名找到包裏面的數據文件,而後讀取爲bytes型的數據。若是數據文件內容是字符串,那麼直接 decode()之後就是正文內容了。

使用 pkgutil還有一個好處,就是隻要知道包名就能夠找到對應包下面的數據文件,數據文件並不必定要在當前包裏面。

例如修改代碼結構以下圖所示:
![](https://s4.51cto.com/images/blog/202012/03/0aea96302a741aca21a8bd7050bc450a.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

另外一個包 test_2裏面有一個數據文件 data2.txt。此時若是要在 teat_1包的 read.py中讀取 data2.txt中的內容,那麼只須要修改 pkgutil.get_data的第一個參數爲 test_2,第二個參數爲數據文件的名字便可,運行效果以下圖所示:
![](https://s4.51cto.com/images/blog/202012/03/93cc8268702bddd6bbe18f80ff73a7d6.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

而前兩種方法都不如 pkgutil簡單。

因此使用 pkgutil能夠大大簡化讀取包裏面的數據文件的代碼。

> 封面圖片做者:產品經理

kingname
相關文章
相關標籤/搜索