"pkgutil" --- 包扩展工具
************************

**源代码:** Lib/pkgutil.py

======================================================================

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

class pkgutil.ModuleInfo(module_finder, name, ispkg)

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

   Added in version 3.6.

pkgutil.extend_path(path, name)

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

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

   对于 "sys.path" 中每个具有与该包名称相匹配的子目录的目录，将该子目
   录添加到包的 "__path__"。 这在需要将单个逻辑包的不同部分拆分为多个
   目录的情况下很有用处。

   它还会查找开头部分 "*" 匹配 *name* 参数的 "*.pkg" 文件。 此特性与
   "*.pth" 文件类似（参阅 "site" 模块了解更多信息），区别在于它不会区
   别对待以 "import" 开头的行。 "*.pkg" 文件会按字面值来接受：除了跳过
   空行和忽略注释，在 "*.pkg" 文件中找到的所有条目都会被添加到路径中，
   无论它们是否存在于文件系统中（这是个有意为之的特性）。

   如果输入路径不是一个列表（已冻结包就是这种情况）则它将被原样返回。
   输入路径不会被修改；将返回一个扩展的副本。 条目将被添加到副本的末尾
   。

   "sys.path" 会被假定为一个序列。 "sys.path" 中的条目如果不是指向现有
   目录的字符串则会被忽略。 "sys.path" 上当用作文件名时会导致错误的
   Unicode 条目可能会使得此函数引发异常（与 "os.path.isdir()" 的行为一
   致）。

pkgutil.get_importer(path_item)

   为给定的 *path_item* 获取一个 *finder*。

   返回的查找器如果是由一个路径钩子新建的则会被缓存至
   "sys.path_importer_cache"。

   如果需要重新扫描 "sys.path_hooks" 则缓存（或其一部分）可以被手动清
   空。

   在 3.3 版本发生变更: 更新为直接基于 "importlib" 而不是依赖于包内部
   的 **PEP 302** 导入模拟。

pkgutil.iter_importers(fullname='')

   为给定的模块名称产生 *finder* 对象。

   如果 *fullname* 包含一个 "'.'"，查找器将针对包含该 *fullname* 的包
   ，否则它们将是所有已注册的最高层级查找器 (即同时位于
   "sys.meta_path" 和 "sys.path_hooks")。

   如果指定的模块位于一个包内，则该包会作为调用此函数的附带影响被导入
   。

   如果未指定模块名称，则会产生所有的最高层级查找器。

   在 3.3 版本发生变更: 更新为直接基于 "importlib" 而不是依赖于包内部
   的 **PEP 302** 导入模拟。

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

   为 *path* 上的所有子模块产生 "ModuleInfo"，或者如果 *path* 为
   "None"，则为 "sys.path" 上的所有最高层级模块产生。

   *path* 应当为 "None" 或一个作为查找模块目标的路径的列表。

   *prefix* 是要在输出时输出到每个模块名称之前的字符串。

   备注:

     只适用于定义了 "iter_modules()" 方法的 *finder*。 该接口是非标准
     的，因此本模块还提供了针对 "importlib.machinery.FileFinder" 和
     "zipimport.zipimporter" 的实现。

   在 3.3 版本发生变更: 更新为直接基于 "importlib" 而不是依赖于包内部
   的 **PEP 302** 导入模拟。

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

   在 *path* 上递归地为所有模块产生 "ModuleInfo"，或者如果 *path* 为
   "None"，则为所有可访问的模块产生。

   *path* 应当为 "None" 或一个作为查找模块目标的路径的列表。

   *prefix* 是要在输出时输出到每个模块名称之前的字符串。

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

   *onerror* 是一个函数，当试图导入包的过程中发生任何异常时将附带一个
   参数（正在被导入的包的名称）被调用。 如果没有提供 *onerror* 函数，
   则 "ImportError" 会被捕获并被忽略，而其他异常则会被传播，导致模块搜
   索的终结。

   示例:

      # 列出 python 可访问的所有模块
      walk_packages()

      # 列出 ctypes 的所有子模块
      walk_packages(ctypes.__path__, ctypes.__name__ + '.')

   备注:

     只适用于定义了 "iter_modules()" 方法的 *finder*。 该接口是非标准
     的，因此本模块还提供了针对 "importlib.machinery.FileFinder" 和
     "zipimport.zipimporter" 的实现。

   在 3.3 版本发生变更: 更新为直接基于 "importlib" 而不是依赖于包内部
   的 **PEP 302** 导入模拟。

pkgutil.get_data(package, resource)

   从包中获取一个资源。

   This is a wrapper for the *loader* "get_data" API.  The *package*
   argument should be the name of a package, in standard module format
   ("foo.bar").  The *resource* argument should be in the form of a
   relative filename, using "/" as the path separator.

   返回指定资源内容的二进制串。

   This function uses the *loader* method "get_data()" to support
   modules installed in the filesystem, but also in zip files,
   databases, or elsewhere.

   对于位于文件系统中，已经被导入的包来说，这大致等价于:

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

   Like the "open()" function, "get_data()" can follow parent
   directories ("../") and absolute paths (starting with "/" or "C:/",
   for example). It can open compilation/installation artifacts like
   ".py" and ".pyc" files or files with "reserved filenames". To be
   compatible with non-filesystem loaders, avoid using these features.

   警告:

     This function is intended for trusted input. It does not verify
     that *resource* "belongs" to *package*.

   If you use a user-provided *resource* path, consider verifying it.
   For example, require an alphanumeric filename with a known
   extension, or install and check a list of known resources.

   如果指定的包无法被定位或加载，或者如果它使用了不支持 "get_data" 的
   *loader*，则将返回 "None"。 特别地，针对 *命名空间包* 的 *loader*
   不支持 "get_data"。

   参见:

     The "importlib.resources" module provides structured access to
     module resources.

pkgutil.resolve_name(name, *, strict=False)

   将一个名称解析为对象。

   此功能被用在标准库的许多地方 (参见 bpo-12915) —— 并且等价的功能也被
   广泛用于第三方包例如 setuptools, Django 和 Pyramid。

   预期 *name* 将为以下格式之一，其中 W 是一个有效的 Python 标识符的缩
   写而点号表示这些伪正则表达式中的句点字面值:

   * "W(.W)*"

   * "W(.W)*:(W(.W)*)?"

   * "W(.W)*:(W(.W)*)"

   第一种形式只是为了保持向下兼容性。 它假定带点号名称的某一部分是包，
   而其余部分则是该包内部的一个对象，并可能嵌套在其他对象之内。 因为包
   和对象层级结构之间的分界点无法通过观察来确定，所以使用这种形式必须
   重复尝试导入。

   在第二种形式中，调用方通过提供一个单独冒号来明确分界点：冒号左边的
   带点号名称是要导入的包，而冒号右边的带点号名称则是对象层级结构。 使
   用这种形式只需要导入一次。 如果它以冒号结尾，则将返回一个模块对象。

   The first two forms are accepted when "strict=False" (the default).

   The third form requires both the module name and callable,
   separated by a colon. Only this form is accepted when
   "strict=True".

   此函数将返回一个对象（可能为模块），或是引发下列异常之一:

   "ValueError" -- 如果 *name* 不为可识别的格式。

   "ImportError" -- 如果导入本应成功但却失败。

   "AttributeError" -- 当在遍历所导入包的对象层级结构以获取想要的对象
   时遭遇失败。

   Added in version 3.9.

   在 3.15 版本发生变更: The optional keyword-only "strict" flag was
   added.
