# 31.1. `zipimport` - 从Zip档案导入模块

此模块添加了从ZIP格式的归档中导入Python模块（`*.py`，`*.py[co]`）和软件包的功能。通常不需要显式地使用`zipimport`模块；它由内部`import`机制自动用于作为ZIP压缩文件路径的`sys.path`项目。

通常，`sys.path`是作为字符串的目录名称列表。该模块还允许`sys.path`的项目是一个命名ZIP文件归档的字符串。ZIP存档可以包含一个子目录结构以支持包导入，并且可以指定存档内的路径仅从子目录导入。例如，路径`example.zip/lib/`将只从归档中的`lib/`子目录导入。

ZIP存档中可能存在任何文件，但只有文件`.py`和`.pyc`可供导入。不允许动态模块的ZIP导入（`.pyd`，`.so`）。请注意，如果归档只包含`.py`文件，则Python不会尝试通过添加相应的`.pyc`文件来修改归档文件，这意味着如果ZIP归档文件不存在包含`.pyc`文件，导入可能会相当缓慢。

目前不支持具有归档注释的ZIP归档。

也可以看看

PKZIP应用笔记
  关于ZIP文件格式的文档由Phil Katz，使用的格式和算法的创建者。
PEP 273 - 从Zip档案库导入模块
  作者James C. Ahlstrom，他也提供了一个实现。Python 2.3遵循PEP 273中的规范，但使用由Just van Rossum编写的使用PEP 302中描述的导入钩子的实现。
PEP 302 - 新的导入挂钩
  PEP添加了帮助这个模块工作的导入钩子。

此模块定义了一个例外：

exception `zipimport.``ZipImportError`

  zipimporter对象引发的异常。它是`ImportError`的子类，因此也可以作为`ImportError`被捕获。

## 31.1.1. zipimporter对象

`zipimporter`是用于导入ZIP文件的类。

class `zipimport.``zipimporter`(archivepath)

  创建一个新的zipimporter实例。archivepath必须是ZIP文件或ZIP文件中特定路径的路径。For example, an archivepath of `foo/bar.zip/lib` will look for modules in the `lib` directory inside the ZIP file `foo/bar.zip` (provided that it exists).

  如果archivepath未指向有效的ZIP压缩文件，则会引发`ZipImportError`。

  `find_module`(fullname[, path])

    搜索由fullname指定的模块。fullname必须是完全限定（虚线）模块名称。如果找到模块，则返回zipimporter实例本身，如果不是，则返回`None`。可选的路径参数被忽略 - 它与导入器协议兼容。

  `get_code`(fullname)

    返回指定模块的代码对象。如果找不到模块，则引发`ZipImportError`。

  `get_data`(pathname)

    返回与路径名关联的数据。如果找不到文件，则引发`OSError`。

    在版本3.3中更改： `IOError`已升级，而不是`OSError`。

  `get_filename`(fullname)

    返回值`__file__`将被设置为如果指定的模块被导入。如果找不到模块，则引发`ZipImportError`。

    版本3.1中的新功能。

  `get_source`(fullname)

    返回指定模块的源代码。引发`ZipImportError`如果找不到模块，则返回`None`，如果存档包含模块，但没有源。

  `is_package`(fullname)

    如果fullname指定的模块是包，则返回`True`。如果找不到模块，则引发`ZipImportError`。

  `load_module`(fullname)

    加载fullname指定的模块。fullname必须是完全限定（虚线）模块名称。它返回导入的模块，如果找不到，则返回引发`ZipImportError`。

  `archive`

    导入程序的关联ZIP文件的文件名，没有可能的子路径。

  `prefix`

    ZIP文件中搜索模块的子路径。这是指向ZIP文件根目录的zipimporter对象的空字符串。

  与斜杠组合使用时，`archive`和`prefix`属性等于给予`zipimporter`构造函数的原始archivepath 。

## 31.1.2. Examples

以下是从ZIP存档导入模块的示例 - 请注意，未明确使用`zipimport`模块。

    $ unzip -l example.zip
    Archive:  example.zip
      Length     Date   Time    Name
     --------    ----   ----    ----
         8467  11-26-02 22:30   jwzthreading.py
     --------                   -------
         8467                   1 file
    $ ./python
    Python 2.3 (#1, Aug 1 2003, 19:54:32)
    >>> import sys
    >>> sys.path.insert(0, 'example.zip')  # Add .zip file to front of path
    >>> import jwzthreading
    >>> jwzthreading.__file__
    'example.zip/jwzthreading.py'