pkgutil — 包扩展工具

源代码: Lib/pkgutil.py


该模块为导入系统提供了工具,尤其是在包支持方面。

class pkgutil.ModuleInfo(module_finder, name, ispkg)

一个包含模块信息的简短摘要的命名元组。

3.6 新版功能.

pkgutil.extend_path(path, name)

扩展包组成的模块的搜索路径。打算使用的是将以下代码放在包的 __init__.py:

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

This will add to the package’s __path__ all subdirectories of directories on sys.path named after the package. This is useful if one wants to distribute different parts of a single logical package as multiple directories.

它还会查找 *.pkg 文件开始,从 * 匹配 name 参数的地方开始。这个特性类似于 *.pth 文件(请参阅 site 模块获取更多信息),除了它没有以 import 开头的特殊行。*.pkg 文件表面上是可信的:除了检查重复,所有条目都在 *.pkg 文件被添加到该路径,无论它们是否存在于文件系统中。(这是一个特性。)

如果输入路径不是一个列表(就像冻结包的情况一样),它将不加修改地返回。输入路径没有被修改;返回扩展副本。项只被附加到末尾的副本上。

假定 sys.path 是一个序列。不是引用现有目录的字符串的 sys.path 将被忽略。当作为文件名使用时,引起错误的 sys.path 可能会导致此函数引发异常(与 os.path.isdir() 行为一致)。

class pkgutil.ImpImporter(dirname=None)

pep:302 封装 Python 的 “classic” 导入算法的 Finder。

If dirname is a string, a PEP 302 finder is created that searches that directory. If dirname is None, a PEP 302 finder is created that searches the current sys.path, plus any modules that are frozen or built-in.

Note that ImpImporter does not currently support being used by placement on sys.meta_path.

3.3 版后已移除: This emulation is no longer needed, as the standard import mechanism is now fully PEP 302 compliant and available in importlib.

class pkgutil.ImpLoader(fullname, file, filename, etc)

Loader that wraps Python’s “classic” import algorithm.

3.3 版后已移除: This emulation is no longer needed, as the standard import mechanism is now fully PEP 302 compliant and available in importlib.

pkgutil.find_loader(fullname)

检索给定 fullname 的模块 loader

这是向后兼容包装 importlib.util.find_spec(),它将大多数失败转换为 ImportError,并且只返回 loader 而不是完整的 ModuleSpec

在 3.3 版更改: 更新为直接基于 importlib 而不是依赖于包内部 PEP 302 导入仿真。

在 3.4 版更改: 基于 PEP 451 更新

pkgutil.get_importer(path_item)

为给定的 path_item 检索 finder

返回的 finder 被缓存在 sys.path_importer_cache 中,如果它是由路径钩子新创建的。

如果重新扫描 sys.path_hooks 是必要的,可以手动清除缓存(或部分缓存)。

在 3.3 版更改: 更新为直接基于 importlib 而不是依赖于包内部 PEP 302 导入仿真。

pkgutil.get_loader(module_or_name)

module_or_name 获得 loader 对象。

如果该模块或包可以通过正常的导入机制访问,则返回围绕该机制相关部分的包装器。如果无法找到或导入模块,则返回 None。如果命名的模块还没有被导入,它包含的包(如果有的话)会被导入,以建立包 __path__

在 3.3 版更改: 更新为直接基于 importlib 而不是依赖于包内部 PEP 302 导入仿真。

在 3.4 版更改: 基于 PEP 451 更新

pkgutil.iter_importers(fullname='')

为给定模块名称生成 finder 对象。

If fullname contains a '.', the finders will be for the package containing fullname, otherwise they will be all registered top level finders (i.e. those on both sys.meta_path and sys.path_hooks).

如果命名的模块在一个包中,这个包会作为调用这个函数的副作用被导入。

如果未指定模块名,则生成所有顶级查找器。

在 3.3 版更改: 更新为直接基于 importlib 而不是依赖于包内部 PEP 302 导入仿真。

pkgutil.iter_modules(path=None, prefix='')

Yields ModuleInfo for all submodules on path, or, if path is None, all top-level modules on sys.path.

path 应该是 None 或用于查找模块的路径列表。

prefix 是一个字符串,输出时放在每个模块名称的前面。

备注

只适用于 finder,它定义了 iter_modules() 方法。这个接口是非标准的,所以模块也提供了 importlib.machinery.FileFinderzipimport.zipimporter 的实现。

在 3.3 版更改: 更新为直接基于 importlib 而不是依赖于包内部 PEP 302 导入仿真。

pkgutil.walk_packages(path=None, prefix='', onerror=None)

path 上的所有模块递归地生成 ModuleInfo ,或者,如果 pathNone,则为所有可访问模块。

path 应该是 None 或用于查找模块的路径列表。

prefix 是一个字符串,输出时放在每个模块名称的前面。

注意这个函数必须导入给定 path 上的所有 packages而不是 所有模块!),以便访问 __path__ 属性来查找子模块。

onerror 是一个函数,如果在尝试导入一个包时发生任何异常,它将被调用一个参数(被导入的包的名称)。如果没有提供 onerror 函数,ImportError 会被捕获并忽略,而所有其他异常都会被传播,从而终止搜索。

示例:

# list all modules python can access
walk_packages()

# list all submodules of ctypes
walk_packages(ctypes.__path__, ctypes.__name__ + '.')

备注

只适用于 finder,它定义了 iter_modules() 方法。这个接口是非标准的,所以模块也提供了 importlib.machinery.FileFinderzipimport.zipimporter 的实现。

在 3.3 版更改: 更新为直接基于 importlib 而不是依赖于包内部 PEP 302 导入仿真。

pkgutil.get_data(package, resource)

从包中获取资源。

这是 loader get_data API 的包装器。package 参数应该是包的名字,采用标准模块格式(foo.bar)。resource 参数应该以相对文件名的形式存在,使用 / 作为路径分隔符。父目录名 .. 不允许使用,也不允许使用根名称(以 / 开头)。

函数返回二进制字符串,它是指定资源的内容。

对于文件系统中已经导入的包,这大致相当于:

d = os.path.dirname(sys.modules[package].__file__)
data = open(os.path.join(d, resource), 'rb').read()

如果包无法定位或加载,或者它使用了 loader,而该 loader 不支持 get_data,则返回 None。特别是 命名空间包loader 不支持 get_data

pkgutil.resolve_name(name)

将名称解析为对象。

这个功能在标准库的许多地方都有使用(参见 bpo-12915),同样的功能也在广泛使用的第三方包中,如 setuptools、Django 和 Pyramid。

预计 name 将是以下格式之一的字符串,其中 W 是有效的 Python 标识符的缩写,而在这些伪正则表达式中,点代表 literal 句点:

  • W(.W)*

  • W(.W)*:(W(.W)*)?

第一种形式仅用于向后兼容。它假设带点的名称的某些部分是一个包,其余部分是包中某个位置的一个对象,可能嵌套在其他对象中。因为不能通过检查推断出包停止的位置和对象层次结构开始的位置,所以必须使用这个表单重复尝试导入。

在第二种形式中,调用者通过提供一个冒号来明确划分点:冒号左边的带点名称是要导入的包,右边的带点名称是包中的对象层次结构。此形式中只需要一次导入。如果以冒号结尾,则返回一个模块对象。

函数将返回一个对象(可能是模块),或引发以下异常之一:

ValueError —— 如果 name 不是一个可识别的格式。

ImportError —— 如果导入在不应该失败的情况下失败。

AttributeError —— 如果在导入的包中遍历对象层次结构以获取所需对象时发生失败。

3.9 新版功能.