importlib.resources – 包資源的讀取、開啟與訪問

原始碼: Lib/importlib/resources/__init__.py


在 3.7 版本加入。

此模組利用 Python 的匯入系統來提供對*包*內*資源*的訪問。

“資源”是與 Python 中的模組或包相關聯的類檔案資源。資源可以直接包含在包中、包內的子目錄中,或是在包外與模組相鄰的位置。資源可以是文字或二進位制。因此,一個包的 Python 模組原始碼 (.py)、編譯產物 (pycache) 和安裝產物(例如目錄中的保留檔名)在技術上都可看作該包的既成事實的資源。但在實踐中,資源主要是指包作者特意暴露的那些非 Python 產物。

資源可以按二進位制或文字模式開啟或讀取。

資源大致類似於目錄中的檔案,但重要的是要記住這只是一個比喻。資源和包**不一定**必須作為物理檔案和目錄存在於檔案系統上:例如,一個包及其資源可以使用 zipimport 從 zip 檔案中匯入。

備註

該模組提供了與 pkg_resources基本資源訪問類似的功能,但沒有該包的效能開銷。這使得讀取包內包含的資源更容易,語義也更穩定和一致。

該模組的獨立向後移植版提供了關於使用 importlib.resources從 pkg_resources 遷移到 importlib.resources 的更多資訊。

希望支援資源讀取的 Loaders 應該按照 importlib.resources.abc.ResourceReader 的規定實現 get_resource_reader(fullname) 方法。

class importlib.resources.Anchor

表示資源的錨點,可以是一個模組物件或一個作為字串的模組名。定義為 Union[str, ModuleType]

importlib.resources.files(anchor: Anchor | None = None)

返回一個 Traversable 物件,它表示資源容器(可以理解為目錄)及其資源(可以理解為檔案)。一個 Traversable 物件可以包含其他容器(可以理解為子目錄)。

anchor 是一個可選的 Anchor。如果錨點是一個包,資源將從該包中解析。如果是一個模組,資源將在該模組的相鄰位置(在同一個包中或包的根目錄)解析。如果省略錨點,則使用呼叫者的模組。

在 3.9 版本中新增。

在 3.12 版本發生變更: package 形參已重新命名為 anchoranchor 現在可以是一個非包模組,如果省略,將預設為呼叫者的模組。為保持相容性,仍然接受 package,但會引發 DeprecationWarning。考慮按位置傳遞錨點,或在舊版 Python 上使用 importlib_resources >= 5.10 以獲得相容的介面。

importlib.resources.as_file(traversable)

給定一個表示檔案或目錄的 Traversable 物件(通常來自 importlib.resources.files()),返回一個可在 with 語句中使用的上下文管理器。該上下文管理器提供一個 pathlib.Path 物件。

退出上下文管理器時,會清理當資源從(例如)zip 檔案中提取時建立的任何臨時檔案或目錄。

當 Traversable 的方法(read_text 等)不足以滿足需求,並且需要檔案系統上的實際檔案或目錄時,請使用 as_file

在 3.9 版本中新增。

在 3.12 版本發生變更: 增加了對代表目錄的 traversable 的支援。

函式式 API

提供了一組簡化的、向後相容的輔助函式。它們允許透過單個函式呼叫來完成常見操作。

對於以下所有函式

  • anchor 是一個 Anchor,與 files() 中一樣。與 files 不同的是,它不可省略。

  • path_names 是相對於錨點的資源路徑名稱的組成部分。例如,要獲取名為 info.txt 的資源的文字內容,請使用

    importlib.resources.read_text(my_module, "info.txt")
    

    Traversable.joinpath 類似,各個路徑組成部分應使用正斜槓(/)作為路徑分隔符。例如,以下兩種方式是等效的

    importlib.resources.read_binary(my_module, "pics/painting.png")
    importlib.resources.read_binary(my_module, "pics", "painting.png")
    

    出於向後相容性的原因,如果給定了多個 path_names,讀取文字的函式需要一個明確的 encoding 引數。例如,要獲取 info/chapter1.txt 的文字,請使用

    importlib.resources.read_text(my_module, "info", "chapter1.txt",
                                  encoding='utf-8')
    
importlib.resources.open_binary(anchor, *path_names)

開啟指定的資源以進行二進位制讀取。

關於 anchorpath_names 的詳細資訊,請參閱引言

此函式返回一個 BinaryIO 物件,即一個以讀取模式開啟的二進位制流。

此函式大致等同於

files(anchor).joinpath(*path_names).open('rb')

在 3.13 版本發生變更: 現已接受多個 path_names

importlib.resources.open_text(anchor, *path_names, encoding='utf-8', errors='strict')

開啟指定的資源以進行文字讀取。預設情況下,內容以嚴格的 UTF-8 格式讀取。

關於 anchorpath_names 的詳細資訊,請參閱引言encodingerrors 的含義與內建函式 open() 中的相同。

出於向後相容性的原因,如果存在多個 path_names,則必須顯式給出 encoding 引數。此限制計劃在 Python 3.15 中移除。

此函式返回一個 TextIO 物件,即一個以讀取模式開啟的文字流。

此函式大致等同於

files(anchor).joinpath(*path_names).open('r', encoding=encoding)

在 3.13 版本發生變更: 現已接受多個 path_namesencodingerrors 必須作為關鍵字引數給出。

importlib.resources.read_binary(anchor, *path_names)

讀取並返回指定資源的內容,格式為 bytes

關於 anchorpath_names 的詳細資訊,請參閱引言

此函式大致等同於

files(anchor).joinpath(*path_names).read_bytes()

在 3.13 版本發生變更: 現已接受多個 path_names

importlib.resources.read_text(anchor, *path_names, encoding='utf-8', errors='strict')

讀取並返回指定資源的內容,格式為 str。預設情況下,內容以嚴格的 UTF-8 格式讀取。

關於 anchorpath_names 的詳細資訊,請參閱引言encodingerrors 的含義與內建函式 open() 中的相同。

出於向後相容性的原因,如果存在多個 path_names,則必須顯式給出 encoding 引數。此限制計劃在 Python 3.15 中移除。

此函式大致等同於

files(anchor).joinpath(*path_names).read_text(encoding=encoding)

在 3.13 版本發生變更: 現已接受多個 path_namesencodingerrors 必須作為關鍵字引數給出。

importlib.resources.path(anchor, *path_names)

提供*資源*的路徑,作為一個實際的檔案系統路徑。此函式返回一個可在 with 語句中使用的上下文管理器。該上下文管理器提供一個 pathlib.Path 物件。

退出上下文管理器時,會清理建立的任何臨時檔案,例如當資源需要從 zip 檔案中提取時。

例如,stat() 方法需要一個實際的檔案系統路徑;可以這樣使用

with importlib.resources.path(anchor, "resource.txt") as fspath:
    result = fspath.stat()

關於 anchorpath_names 的詳細資訊,請參閱引言

此函式大致等同於

as_file(files(anchor).joinpath(*path_names))

在 3.13 版本發生變更: 現已接受多個 path_namesencodingerrors 必須作為關鍵字引數給出。

importlib.resources.is_resource(anchor, *path_names)

如果指定的資源存在,則返回 True,否則返回 False。此函式不將目錄視為資源。

關於 anchorpath_names 的詳細資訊,請參閱引言

此函式大致等同於

files(anchor).joinpath(*path_names).is_file()

在 3.13 版本發生變更: 現已接受多個 path_names

importlib.resources.contents(anchor, *path_names)

返回一個可迭代物件,用於遍歷包或路徑內的命名專案。該可迭代物件返回資源(如檔案)和非資源(如目錄)的名稱,型別為 str。該可迭代物件不會遞迴進入子目錄。

關於 anchorpath_names 的詳細資訊,請參閱引言

此函式大致等同於

for resource in files(anchor).joinpath(*path_names).iterdir():
    yield resource.name

自 3.11 版本起棄用: 推薦使用上述的 iterdir(),它能更好地控制結果並提供更豐富的功能。