31.5. pkgutil —软件包扩展 Util

2.3 版的新Function。

源代码: Lib/pkgutil.py


该模块提供了导入系统的 Util,特别是软件包支持。

  • pkgutil. extend_path(* path name *)
    • 扩展组成包的模块的搜索路径。预期用途是将以下代码放置在包的__init__.py中:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

这会将sys.path上以该软件包命名的目录的所有子目录添加到该软件包的__path__中。如果希望将单个逻辑包的不同部分作为多个目录分发,这将很有用。

它还会从*与* name *参数匹配的地方开始查找*.pkg个文件。此Function类似于*.pth文件(有关更多信息,请参见site模块),不同之处在于它不是以import开头的特殊情况。一个*.pkg文件是可信任的,其面值是:除了检查重复项之外,在*.pkg文件中找到的所有条目都添加到该路径中,而不管它们是否存在于文件系统上。 (这是一个Function.)

如果 Importing 路径不是列表(冻结软件包就是这种情况),则将其保持不变。Importing 路径未修改;返回扩展副本。项目仅在末尾附加到副本中。

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

    • class * pkgutil. ImpImporter(* dirname = None *)
    • PEP 302导入器,用于包装 Python 的“经典”导入算法。

如果* dirname 是字符串,则会创建一个 PEP 302导入程序来搜索该目录。如果 dirname *是None,则会创建一个 PEP 302导入程序,该导入程序搜索当前sys.path以及冻结或内置的所有模块。

请注意,ImpImporter目前不支持被sys.meta_path上的展示位置使用。

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

    • 找到一个 PEP 302“ loader”对象作为* fullname *。

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

  • pkgutil. get_importer(* path_item *)
    • 为给定的* path_item *检索 PEP 302导入器。

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

如果没有 import 商,则返回围绕基本 import 机器的包装器。此包装器永远不会插入到导入器缓存中(而是插入None)。

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

  • pkgutil. get_loader(* module_or_name *)
    • 为* module_or_name *获取 PEP 302“ loader”对象。

如果可以pass常规导入机制访问模块或包,则返回包装该机械相关部分的 Wrapper。如果找不到或导入模块,则返回None。如果尚未导入指定模块,则将导入其包含的包(如果有),以构建包__path__

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

  • pkgutil. iter_importers(* fullname =“''*)
    • 给定模块名称可产生 PEP 302个 import 商。

如果 fullname 包含'.',则导入程序将用于包含 fullname 的程序包,否则,它们将按 Sequences 依次是sys.meta_pathsys.path和 Python 的“经典”导入机制的导入程序。如果指定的模块在软件包中,则导入该软件包是调用此Function的副作用。

标准导入机制用于在其他位置查找文件的非 PEP 302机制(例如 Windows 注册表)受到部分支持,但会在sys.path之后搜索。通常,在sys.path之前*搜索这些位置,以防止sys.path条目遮盖它们。

为了使这种方式在行为上产生明显的差异,必须有一个可以passsys.path和非 PEP 302文件系统机制之一访问的模块或程序包名称。在这种情况下,仿真将找到前一个版本,而内置的导入机制将找到后者。

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

  • pkgutil. iter_modules(* path = None prefix =''*)
    • 为* path *上的所有子模块产生(module_loader, name, ispkg),如果 path 为None,则为sys.path的所有顶级模块产生(module_loader, name, ispkg)
  • path *应该为None或要在其中查找模块的路径列表。

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

  • pkgutil. walk_packages(* path = None prefix ='' onerror = None *)
    • 以递归方式在* path *上为所有模块生成(module_loader, name, ispkg),或者,如果 path 为None,则所有可访问模块的生成。
  • path *应该为None或要在其中查找模块的路径列表。

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

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

  • onerror 是一个函数,如果在try导入软件包时发生任何异常,则使用一个参数(正在导入的软件包的名称)调用该函数。如果没有提供 onerror *Function,则捕获并忽略ImportError,同时传播所有其他异常,从而终止搜索。

Examples:

# 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 版的新Function。