Документация Python неофициальный перевод
Содержание страницы

zipapp – Управление исполняемыми ZIP-архивами Pythonzipapp – Manage executable Python zip archives

Добавлено в версии 3.5.

Исходный код: Lib/zipapp.py


This module provides tools to manage the creation of zip files containing Python code, which can be executed directly by the Python interpreter. The module provides both a Command-Line Interface and a Python API.

Простой примерBasic Example

В следующем примере показано, как с помощью интерфейса командной строки можно создать исполняемый архив из каталога с кодом Python. При запуске архив выполнит функцию main из модуля myapp.

$ python -m zipapp myapp -m "myapp:main"
$ python myapp.pyz
<output from myapp>

Интерфейс командной строкиCommand-Line Interface

При вызове как программы из командной строки используется следующая форма:

$ python -m zipapp source [options]

If source is a directory, this will create an archive from the contents of source. If source is a file, it should be an archive, and it will be copied to the target archive (or the contents of its shebang line will be displayed if the –info option is specified).

Поддерживаются следующие опции:

-o <output>, --output=<output>

Записывает результат в файл с именем output. Если эта опция не указана, имя выходного файла будет таким же, как у входного source, но с добавлением расширения .pyz. Если задано явное имя файла, оно используется как есть (поэтому при необходимости следует указать расширение .pyz).

Имя выходного файла должно быть указано, если source является архивом (в этом случае output не должно совпадать с source).

-p <interpreter>, --python=<interpreter>

Добавляет в архив строку #!, указывающую interpreter в качестве команды для запуска. Также на POSIX делает архив исполняемым. По умолчанию строка #! не записывается, и файл не делается исполняемым.

-m <mainfn>, --main=<mainfn>

Записывает в архив файл __main__.py, который выполняет mainfn. Аргумент mainfn должен иметь вид «pkg.mod:fn», где «pkg.mod» – пакет или модуль в архиве, а «fn» – вызываемый объект в этом модуле. Файл __main__.py выполнит этот вызываемый объект.

--main нельзя указывать при копировании архива.

-c, --compress

Сжимает файлы методом deflate, уменьшая размер выходного файла. По умолчанию файлы хранятся в архиве без сжатия.

--compress не действует при копировании архива.

Добавлено в версии 3.7.

--info

Выводит интерпретатор, встроенный в архив, для диагностики. В этом случае все остальные опции игнорируются, а SOURCE должен быть архивом, а не каталогом.

-h, --help

Выводит краткую справку и завершает работу.

Python API

Модуль определяет две вспомогательные функции:

zipapp.create_archive(source, target=None, interpreter=None, main=None, filter=None, compressed=False)

Создаёт архив приложения из source. Источником может быть любой из перечисленных вариантов:

  • Имя каталога или объект, подобный пути, указывающий на каталог. В этом случае новый архив приложения будет создан из содержимого этого каталога.

  • Имя существующего файла архива приложения или объект, подобный пути, указывающий на такой файл. В этом случае файл копируется в целевой объект (с изменением значения, переданного в аргументе interpreter). При необходимости имя файла должно включать расширение .pyz.

  • Файловый объект, открытый для чтения в байтовом режиме. Содержимое файла должно быть архивом приложения, и предполагается, что файловый объект находится в начале архива.

Аргумент target определяет, куда будет записан результирующий архив:

  • Если это имя файла или объект, подобный пути, архив будет записан в этот файл.

  • Если это открытый файловый объект, архив будет записан в этот файловый объект, который должен быть открыт для записи в байтовом режиме.

  • Если цель опущена (или None), источник должен быть каталогом, и целью будет файл с тем же именем, что и источник, с\добавленным расширением .pyz.

Аргумент interpreter задаёт имя интерпретатора Python, с которым будет выполняться архив. Он записывается в виде строки «shebang» в начале архива. На POSIX эта строка будет интерпретироваться ОС, а на Windows – обрабатываться загрузчиком Python. Если опустить interpreter, строка shebang не записывается. Если интерпретатор указан, а целью является имя файла, то устанавливается бит исполняемости целевого файла.

Аргумент main задаёт имя вызываемого объекта, который будет использоваться как главная программа архива. Его можно указать только в том случае, если источник – каталог и в нём ещё нет файла __main__.py. Аргумент main должен иметь форму «pkg.module:callable», и архив будет выполняться путём импорта «pkg.module» и вызова указанного вызываемого объекта без аргументов. Будет ошибкой опустить main, если источник – каталог и не содержит файла __main__.py, так как иначе полученный архив не будет исполняемым.

Необязательный аргумент filter задаёт функцию обратного вызова, которой передаётся объект Path, представляющий путь к добавляемому файлу (относительно исходного каталога). Она должна возвращать True, если файл следует добавить.

Необязательный аргумент compressed определяет, будут ли файлы сжиматься. Если установлено True, файлы в архиве сжимаются методом deflate; в противном случае файлы хранятся без сжатия. Этот аргумент не влияет на копирование существующего архива.

Если для source или target указан файловый объект, вызывающая сторона обязана закрыть его после вызова create_archive.

При копировании существующего архива предоставленные файловые объекты должны иметь только методы read и readline или write. При создании архива из каталога, если цель – файловый объект, он будет передан классу zipfile.ZipFile и должен предоставлять методы, необходимые этому классу.

Изменено в версии 3.7: Добавлены параметры filter и compressed.

zipapp.get_interpreter(archive)

Возвращает интерпретатор, указанный в строке #! в начале архива. Если строка #! отсутствует, возвращает None. Аргумент archive может быть именем файла или файлоподобным объектом, открытым для чтения в байтовом режиме. Предполагается, что он находится в начале архива.

ПримерыExamples

Упаковывает каталог в архив и запускает его.

$ python -m zipapp myapp
$ python myapp.pyz
<output from myapp>

То же самое можно сделать с помощью функции create_archive():

>>> import zipapp
>>> zipapp.create_archive('myapp', 'myapp.pyz')

Чтобы сделать приложение непосредственно исполняемым на POSIX, укажите интерпретатор для использования.

$ python -m zipapp myapp -p "/usr/bin/env python"
$ ./myapp.pyz
<output from myapp>

Чтобы заменить строку shebang в существующем архиве, создайте изменённый архив с помощью функции create_archive():

>>> import zipapp
>>> zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3')

Чтобы обновить файл на месте, выполните замену в памяти с помощью объекта BytesIO, а затем перезапишите исходный файл. Обратите внимание, что при перезаписи файла на месте существует риск, что ошибка приведёт к потере исходного файла. Данный код не защищает от таких ошибок, но рабочий код должен это делать. Кроме того, этот метод будет работать только в том случае, если архив помещается в память:

>>> import zipapp
>>> import io
>>> temp = io.BytesIO()
>>> zipapp.create_archive('myapp.pyz', temp, '/usr/bin/python2')
>>> with open('myapp.pyz', 'wb') as f:
>>>     f.write(temp.getvalue())

Указание интерпретатораSpecifying the Interpreter

Обратите внимание: если вы указываете интерпретатор и затем распространяете архив своей программы, необходимо убедиться, что используемый интерпретатор переносим. Загрузчик Python для Windows поддерживает большинство распространённых форм строки POSIX #!, но есть другие моменты, которые стоит учесть:

  • Если вы используете «/usr/bin/env python» (или другие формы команды «python», например «/usr/bin/python»), нужно учитывать, что у ваших пользователей может быть установлен по умолчанию как Python 2, так и Python 3, и писать свой код так, чтобы он работал в обеих версиях.

  • Если вы используете явную версию, например «/usr/bin/env python3», ваше приложение не будет работать у пользователей, у которых нет этой версии. (Это может быть тем, что вам нужно, если вы не делали свой код совместимым с Python 2).

  • Невозможно указать «python X.Y или новее», поэтому будьте осторожны с использованием точной версии, например «/usr/bin/env python3.4», так как вам придётся изменить строку shebang для пользователей Python 3.5, например.

Обычно стоит использовать «/usr/bin/env python2» или «/usr/bin/env python3», в зависимости от того, для Python 2 или 3 написан ваш код.

Создание автономных приложений с помощью zipappCreating Standalone Applications with zipapp

С помощью модуля zipapp можно создавать самодостаточные программы на Python, которые можно распространять среди конечных пользователей, которым нужна только подходящая версия Python, установленная в их системе. Ключ к этому – упаковать все зависимости приложения в архив вместе с кодом приложения.

Шаги по созданию автономного архива следующие:

  1. Создайте своё приложение в каталоге обычным образом, чтобы у вас был каталог myapp, содержащий файл __main__.py и любой вспомогательный код приложения.

  2. Установите все зависимости вашего приложения в каталог myapp, используя pip:

    $ python -m pip install -r requirements.txt --target myapp
    

    (предполагается, что требования вашего проекта находятся в файле requirements.txt – если нет, вы можете просто перечислить зависимости вручную в командной строке pip).

  3. Упакуйте приложение с помощью:

    $ python -m zipapp -p "interpreter" myapp
    

Это создаст автономный исполняемый файл, который можно запустить на любой машине с подходящим интерпретатором. Подробнее см. Указание интерпретатора. Его можно распространять среди пользователей как один файл.

В Unix файл myapp.pyz является исполняемым как есть. Вы можете переименовать файл, чтобы удалить расширение .pyz, если предпочитаете «простое» имя команды. В Windows файл myapp.pyz[w] является исполняемым благодаря тому, что интерпретатор Python регистрирует расширения файлов .pyz и .pyzw при установке.

ПредостереженияCaveats

Если ваше приложение зависит от пакета, содержащего C-расширение, этот пакет нельзя запускать из zip-файла (это ограничение ОС: исполняемый код должен находиться в файловой системе, чтобы загрузчик ОС мог его загрузить). В таком случае можно исключить эту зависимость из zip-файла и либо потребовать от пользователей её установки, либо поставлять её вместе с zip-файлом и добавить код в __main__.py, чтобы включить каталог, содержащий распакованный модуль, в sys.path. В этом случае нужно убедиться, что поставляются подходящие бинарные файлы для целевой архитектуры (и, возможно, выбирать правильную версию для добавления в sys.path во время выполнения в зависимости от машины пользователя).

Формат zip-архива приложений PythonThe Python Zip Application Archive Format

Python умеет выполнять zip-файлы, содержащие файл __main__.py, начиная с версии 2.6. Чтобы Python мог выполнить архив приложения, он должен быть обычным zip-файлом, содержащим файл __main__.py, который будет запущен как точка входа приложения. Как и для любого скрипта Python, родительский каталог скрипта (в данном случае zip-файл) будет добавлен в sys.path, и, таким образом, другие модули можно будет импортировать из zip-файла.

Формат zip-файлов позволяет добавлять произвольные данные в начало zip-файла. Формат архива приложений использует эту возможность для добавления стандартной POSIX-строки «шебанг» в начало файла (#!/path/to/interpreter).

Формально формат zip-архива приложений Python определяется так:

  1. Необязательная строка шебанга, содержащая символы b'#!', за которыми следует имя интерпретатора, а затем символ новой строки (b'\n'). Имя интерпретатора может быть любым, приемлемым для обработки шебанга в ОС или для загрузчика Python в Windows. На Windows интерпретатор должен быть закодирован в UTF-8, а на POSIX – в sys.getfilesystemencoding().

  2. Стандартные данные zip-файла, создаваемые модулем zipfile. Содержимое zip-файла должно включать файл с именем __main__.py (который должен находиться в «корне» zip-файла, то есть не в подкаталоге). Данные zip-файла могут быть сжатыми или несжатыми.

Если архив приложения содержит строку шебанга, на POSIX-системах у него может быть установлен бит исполняемости, чтобы его можно было запускать напрямую.

Не требуется, чтобы архивы приложений создавались с помощью инструментов из этого модуля – модуль предоставляет удобные средства, но архивы указанного формата, созданные любым способом, принимаются Python.