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)
方法。
- importlib.resources.files(anchor: Anchor | None = None)¶
返回一个
Traversable
对象,它表示资源容器(可以理解为目录)及其资源(可以理解为文件)。一个 Traversable 对象可以包含其他容器(可以理解为子目录)。anchor 是一个可选的
Anchor
。如果锚点是一个包,资源将从该包中解析。如果是一个模块,资源将在该模块的相邻位置(在同一个包中或包的根目录)解析。如果省略锚点,则使用调用者的模块。在 3.9 版本中新增。
在 3.12 版本发生变更: package 形参已重命名为 anchor。anchor 现在可以是一个非包模块,如果省略,将默认为调用者的模块。为保持兼容性,仍然接受 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¶
提供了一组简化的、向后兼容的辅助函数。它们允许通过单个函数调用来完成常见操作。
对于以下所有函数
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)¶
打开指定的资源以进行二进制读取。
关于 anchor 和 path_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 格式读取。
关于 anchor 和 path_names 的详细信息,请参阅引言。encoding 和 errors 的含义与内置函数
open()
中的相同。出于向后兼容性的原因,如果存在多个 path_names,则必须显式给出 encoding 参数。此限制计划在 Python 3.15 中移除。
此函数返回一个
TextIO
对象,即一个以读取模式打开的文本流。此函数大致等同于
files(anchor).joinpath(*path_names).open('r', encoding=encoding)
在 3.13 版本发生变更: 现已接受多个 path_names。encoding 和 errors 必须作为关键字参数给出。
- importlib.resources.read_binary(anchor, *path_names)¶
读取并返回指定资源的内容,格式为
bytes
。关于 anchor 和 path_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 格式读取。关于 anchor 和 path_names 的详细信息,请参阅引言。encoding 和 errors 的含义与内置函数
open()
中的相同。出于向后兼容性的原因,如果存在多个 path_names,则必须显式给出 encoding 参数。此限制计划在 Python 3.15 中移除。
此函数大致等同于
files(anchor).joinpath(*path_names).read_text(encoding=encoding)
在 3.13 版本发生变更: 现已接受多个 path_names。encoding 和 errors 必须作为关键字参数给出。
- importlib.resources.path(anchor, *path_names)¶
提供*资源*的路径,作为一个实际的文件系统路径。此函数返回一个可在
with
语句中使用的上下文管理器。该上下文管理器提供一个pathlib.Path
对象。退出上下文管理器时,会清理创建的任何临时文件,例如当资源需要从 zip 文件中提取时。
例如,
stat()
方法需要一个实际的文件系统路径;可以这样使用with importlib.resources.path(anchor, "resource.txt") as fspath: result = fspath.stat()
关于 anchor 和 path_names 的详细信息,请参阅引言。
此函数大致等同于
as_file(files(anchor).joinpath(*path_names))
在 3.13 版本发生变更: 现已接受多个 path_names。encoding 和 errors 必须作为关键字参数给出。
- importlib.resources.is_resource(anchor, *path_names)¶
如果指定的资源存在,则返回
True
,否则返回False
。此函数不将目录视为资源。关于 anchor 和 path_names 的详细信息,请参阅引言。
此函数大致等同于
files(anchor).joinpath(*path_names).is_file()
在 3.13 版本发生变更: 现已接受多个 path_names。
- importlib.resources.contents(anchor, *path_names)¶
返回一个可迭代对象,用于遍历包或路径内的命名项目。该可迭代对象返回资源(如文件)和非资源(如目录)的名称,类型为
str
。该可迭代对象不会递归进入子目录。关于 anchor 和 path_names 的详细信息,请参阅引言。
此函数大致等同于
for resource in files(anchor).joinpath(*path_names).iterdir(): yield resource.name
自 3.11 版本起弃用: 推荐使用上述的
iterdir()
,它能更好地控制结果并提供更丰富的功能。