31.5. pkgutil — 包扩展实用程序 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/pkgutil
跳转至:导航、​搜索

31.5. 实用程序 — 包扩展实用程序

2.3 版中的新功能。


源代码: :source:`Lib/pkgutil.py`



该模块为导入系统提供实用程序,特别是包支持。

pkgutil.extend_path(path, name)

扩展组成包的模块的搜索路径。 预期用途是将以下代码放在包的 __init__.py 中:

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

这会将 sys.path 上以包命名的目录的所有子目录添加到包的 __path__。 如果想要将单个逻辑包的不同部分作为多个目录分发,这将非常有用。

它还查找 *.pkg 文件,其中 *name 参数匹配。 此功能类似于 *.pth 文件(有关更多信息,请参阅 site 模块),除了它不包含以 import 开头的特殊行。 *.pkg 文件从表面上看是可信的:除了检查重复项外,在 *.pkg 文件中找到的所有条目都会添加到路径中,无论它们是否存在于文件系统中。 (这是一个功能。)

如果输入路径不是列表(如冷冻包的情况),则返回不变。 输入路径未修改; 返回扩展副本。 项目仅附加到副本的末尾。

假设 sys.path 是一个序列。 sys.path 中不是(Unicode 或 8 位)字符串的引用现有目录的项目将被忽略。 sys.path 上的 Unicode 项目在用作文件名时会导致错误可能会导致此函数引发异常(符合 os.path.isdir() 行为)。

class pkgutil.ImpImporter(dirname=None)

PEP 302 包含 Python 的“经典”导入算法的导入器。

如果 dirname 是一个字符串,则会创建一个 PEP 302 导入器来搜索该目录。 如果 dirnameNone,则会创建一个 PEP 302 导入器,用于搜索当前的 sys.path,加上任何冻结或内置的模块。

请注意,ImpImporter 目前不支持通过放置在 sys.meta_path 上使用。

class pkgutil.ImpLoader(fullname, file, filename, etc)
PEP 302 包装 Python 的“经典”导入算法的加载器。
pkgutil.find_loader(fullname)

fullname 找到一个 PEP 302 “loader”对象。

如果 fullname 包含点,路径必须是包含包的 __path__。 如果无法找到或导入模块,则返回 None。 此函数使用 iter_importers(),因此在特定于平台的特殊导入位置(例如 Windows 注册表)方面受到相同限制。

pkgutil.get_importer(path_item)

为给定的 path_item 检索 PEP 302 导入器。

如果返回的导入器是由路径挂钩新创建的,则它会缓存在 sys.path_importer_cache 中。

如果没有进口商,则退回基本进口机器的包装纸。 这个包装器永远不会插入到导入器缓存中(而是插入 None)。

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

pkgutil.get_loader(module_or_name)

module_or_name 获取一个 PEP 302 “loader”对象。

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

此函数使用 iter_importers(),因此在特定于平台的特殊导入位置(例如 Windows 注册表)方面受到相同限制。

pkgutil.iter_importers(fullname=)

为给定的模块名称生成 PEP 302 导入器。

如果 fullname 包含 '.',则导入器将用于包含 fullname 的包,否则它们将是 sys.meta_pathsys.path 和 Python 的“经典”导入的导入器机械,按这个顺序。 如果命名模块在一个包中,则该包将作为调用此函数的副作用而被导入。

PEP 302 机制(例如 部分支持标准导入机制用于在替代位置查找文件的 Windows 注册表,但会在 sys.path 之后搜索 。 通常,这些位置在 sys.path 之前搜索 ,防止 sys.path 条目隐藏它们。

为了导致行为上的明显差异,必须有一个模块或包名称可通过 sys.path 和非 PEP 302[ X177X] 文件系统机制。 在这种情况下,仿真会找到前一个版本,而内置的导入机制会找到后者。

以下类型的项目可能受此差异影响:imp.C_EXTENSIONimp.PY_SOURCEimp.PY_COMPILEDimp.PKG_DIRECTORY

pkgutil.iter_modules(path=None, prefix=)

路径 上的所有子模块产生 (module_loader, name, ispkg),或者,如果路径为 None,则产生 sys.path 上的所有顶级模块。

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

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

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

path 上递归地为所有模块产生 (module_loader, name, ispkg),或者,如果路径是 None,所有可访问的模块。

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

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

请注意,此函数必须在给定的 路径 上导入所有 不是 所有模块!),以便访问 __path__ 属性到找到子模块。

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

例子:

# list all modules python can access
walk_packages()

# list all submodules of ctypes
walk_packages(ctypes.__path__, ctypes.__name__ + '.')
pkgutil.get_data(package, resource)

从包中获取资源。

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

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

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

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

如果无法定位或加载包,或者它使用不支持 get_data()PEP 302 加载器,则 None 是回来。

2.6 版中的新功能。