# `zipimport` --- 從 Zip 封存檔案匯入模組

原始碼：Lib/zipimport.py

此模組新增了從 ZIP 格式封存檔案中引入 Python 模組（`*.py`、`*.pyc`）和套件的能力。通常不需要明確地使用 `zipimport` 模組；對於 `sys.path` 中指向 ZIP 封存檔案路徑的項目，內建的 `import` 機制會自動使用它。

通常 `sys.path` 是一個由目錄名稱字串組成的串列。此模組也允許 `sys.path` 的一個項目是命名 ZIP 封存檔案的字串。ZIP 封存檔案可以包含子目錄結構以支援套件引入，並且可以指定封存檔案內的路徑以僅從子目錄中引入。例如路徑 `example.zip/lib/` 將只會從封存檔案內的 `lib/` 子目錄中引入。

ZIP 封存檔案中可以存在任何檔案，但引入器只會對 `.py` 和 `.pyc` 檔案起作用。不允許從 ZIP 引入動態模組（`.pyd`、`.so`）。請注意，如果封存檔案只包含 `.py` 檔案，Python 將不會試圖透過新增對應的 `.pyc` 檔案來修改封存檔案，這意味著如果 ZIP 封存檔案不包含 `.pyc` 檔案，引入可能會相當慢。

在 3.15 版的變更: Zstandard (zstd) compressed zip file entries are supported.

在 3.13 版的變更: 支援 ZIP64。

在 3.8 版的變更: 在過去，不支援帶有封存檔案註解的 ZIP 封存檔案。

也參考

PKZIP Application Note

  由 ZIP 格式和所用演算法的創造者 Phil Katz 編寫的關於 ZIP 檔案格式的文件。

PEP 273 - 從 Zip 封存檔案引入模組

  由 James C. Ahlstrom 編寫，他也提供了一個實作。Python 2.3 遵循 PEP 273 中的規範，但使用由 Just van Rossum 編寫的實作，該實作使用了 PEP 302 中描述的引入掛鉤。

`importlib` - 引入機制的實作

  提供所有引入器要實作的相關協定的套件。

此模組定義了一個例外：

exception zipimport.ZipImportError

  由 zipimporter 物件引發的例外。它是 `ImportError` 的子類別，所以也可以被捕捉為 `ImportError`。

## zipimporter 物件

`zipimporter` 是用於引入 ZIP 檔案的類別。

class zipimport.zipimporter(archivepath)

  建立一個新的 zipimporter 實例。archivepath 必須是 ZIP 檔案的路徑，或是 ZIP 檔案內的特定路徑。例如，`foo/bar.zip/lib` 的 archivepath 將會在 ZIP 檔案 `foo/bar.zip` 內的 `lib` 目錄中尋找模組（如果該目錄存在的話）。

  如果 archivepath 未指向一個有效的 ZIP 封存檔案，則會引發 `ZipImportError`。

  在 3.12 版的變更: 在 3.10 版中已棄用的 `find_loader()` 和 `find_module()` 方法現已被移除。請改用 `find_spec()`。

  create_module(spec)

    `importlib.abc.Loader.create_module()` 的實作，回傳 `None` 以明確請求預設語意。

    在 3.10 版被加入.

  exec_module(module)

    `importlib.abc.Loader.exec_module()` 的實作。

    在 3.10 版被加入.

  find_spec(fullname, target=None)

    `importlib.abc.PathEntryFinder.find_spec()` 的一個實作。

    在 3.10 版被加入.

  get_code(fullname)

    回傳指定模組的程式碼物件。如果模組無法被引入，則引發 `ZipImportError`。

  get_data(pathname)

    回傳與 pathname 相關的資料。如果找不到檔案，則引發 `OSError`。

    在 3.3 版的變更: 過去會引發 `IOError`，現在它是 `OSError` 的別名。

  get_filename(fullname)

    回傳如果指定模組被引入時 `__file__` 會被設定的值。如果模組無法被引入，則引發 `ZipImportError`。

    在 3.1 版被加入.

  get_source(fullname)

    回傳指定模組的原始碼。如果找不到模組，則引發 `ZipImportError`；如果封存檔案包含該模組但沒有其原始碼，則回傳 `None`。

  is_package(fullname)

    如果由 fullname 指定的模組是一個套件，則回傳 `True`。如果找不到模組，則引發 `ZipImportError`。

  invalidate_caches()

    清除關於在 ZIP 封存檔案中找到的檔案資訊的內部快取。

    在 3.10 版被加入.

  archive

    引入器關聯的 ZIP 檔案的檔名，不包含可能的子路徑。

  prefix

    在 ZIP 檔案內搜尋模組的子路徑。對於指向 ZIP 檔案根目錄的 zipimporter 物件，這是一個空字串。

  `archive` 和 `prefix` 屬性（attribute），當用斜線組合時，等於給予 `zipimporter` 建構函式的原始 archivepath 引數。

## 範例

這是一個從 ZIP 封存檔案引入模組的範例——請注意，`zipimport` 模組並未被明確使用。

    $ unzip -l example_archive.zip
    Archive:  example_archive.zip
      Length     Date   Time    Name
     --------    ----   ----    ----
         8467  01-01-00 12:30   example.py
     --------                   -------
         8467                   1 file

    >>> import sys
    >>> # 將封存檔案新增到系統路徑的最前面
    >>> sys.path.insert(0, 'example_archive.zip')
    >>> import example
    >>> example.__file__
    'example_archive.zip/example.py'