# 31.2. `pkgutil` - 软件包扩展实用程序

源代码： Lib / pkgutil.py

此模块为导入系统提供实用程序，特别是软件包支持。

`pkgutil.``extend_path`(path, name)

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

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

  这将向包的`__path__`添加在包之后命名的`sys.path`上的目录的所有子目录。如果想要将单个逻辑包的不同部分分布为多个目录，这将非常有用。

  它还会查找`*`开头的`*.pkg`文件是否与名称参数匹配。此功能类似于`*.pth`文件（有关详细信息，请参阅`site`模块），但不包含以`import` A `*.pkg`文件以面值信任：除了检查重复之外，在`*.pkg`文件中找到的所有条目都添加到路径，存在于文件系统上。（这是功能。）

  如果输入路径不是列表（如冻结包的情况），则返回不变。输入路径不修改；将返回扩展副本。项目仅附加到末尾的副本。

  假设`sys.path`是一个序列。不是指向现有目录的字符的`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`上的展示位置使用。

  自版本3.3后已弃用：此模拟不再需要，因为标准导入机制现在完全符合PEP 302，并且在`importlib`中可用。

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

  PEP 302加载器，它包装Python的“经典”导入算法。

  自版本3.3后已弃用：此模拟不再需要，因为标准导入机制现在完全符合PEP 302，并且在`importlib`中可用。

`pkgutil.``find_loader`(fullname)

  针对给定的全名，检索 PEP 302模块加载程序。

  这是`importlib.util.find_spec()`的向后兼容性封装，将大多数失败转换为`ImportError`，只返回加载器而不是完整的`ModuleSpec`

  在版本3.3中更改：更新为直接基于`importlib`，而不是依赖程序包内部PEP 302导入仿真。

  在版本3.4中已更改：更新为基于 PEP 451

`pkgutil.``get_importer`(path_item)

  针对给定的path_item，检索 PEP 302导入器。

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

  如果需要重新扫描`sys.path_hooks`，则可以手动清除高速缓存（或其一部分）。

  在版本3.3中更改：更新为直接基于`importlib`，而不是依赖程序包内部PEP 302导入仿真。

`pkgutil.``get_loader`(module_or_name)

  为module_or_name获取 PEP 302“loader”对象。

  如果模块或包可以通过正常的导入机制访问，则返回该机器的相关部分周围的包装。如果无法找到或导入模块，则返回`None`。如果指定的模块尚未导入，则将导入其包含的包（如果有），以建立包`__path__`。

  在版本3.3中更改：更新为直接基于`importlib`，而不是依赖程序包内部PEP 302导入仿真。

  在版本3.4中已更改：更新为基于 PEP 451

`pkgutil.``iter_importers`(fullname='')

  给定模块名称的产出 PEP 302导入器。

  如果fullname包含'。'，进口商将是包含fullname的包，否则它们将是所有注册的顶级进口商。那些在sys.meta_path和sys.path_hooks）。

  如果命名模块在包中，则该包将作为调用此函数的副作用导入。

  如果未指定模块名称，则会生成所有顶级导入器。

  在版本3.3中更改：更新为直接基于`importlib`，而不是依赖程序包内部PEP 302导入仿真。

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

  对路径上的所有子模块，产生`（module_finder， 名称， ispkg） ，如果路径为`None`，则`sys.path`上的所有顶级模块。`

  路径应为`None`或查找模块的路径列表。

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

  注意

  仅适用于定义`iter_modules()`方法的finder。此界面是非标准的，因此该模块还提供了`importlib.machinery.FileFinder`和`zipimport.zipimporter`的实现。

  在版本3.3中更改：更新为直接基于`importlib`，而不是依赖程序包内部PEP 302导入仿真。

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

  对于所有模块在路径上递归生成`（module_finder， 名称， ispkg）或者，如果路径是`None`，所有可访问的模块。`

  路径应为`None`或查找模块的路径列表。

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

  请注意，此函数必须导入所有包（不是所有模块！）在给定的路径上，以访问`__path__`属性以查找子模块。

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

  例子：

      # list all modules python can access
      walk_packages()

      # list all submodules of 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)

  从包中获取资源。

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

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

  对于已经导入的位于文件系统中的包，这是大致相当于：

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

  如果无法找到或加载包，或者使用不支持`get_data()`的 PEP 302加载程序，则`None`。