Spec-Zone.ru › Python 3.13

zipapp — управление исполняемыми ZIP-архивами Python

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

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

Этот модуль предоставляет инструменты для создания ZIP-файлов, содержащих код Python, которые можно запускать непосредственно интерпретатором Python. Модуль предоставляет как интерфейс командной строки, так и API Python.

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

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

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

Интерфейс командной строки

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

$ python -m zipapp source [options]

Если source — это каталог, из его содержимого будет создан архив. Если source — файл, он должен быть архивом; он будет скопирован в целевой архив (или будет показано содержимое его строки shebang, если указан параметр –info).

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

-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

Вывести краткое сообщение об использовании и завершить работу.

API Python

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

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

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

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

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

  • Если это имя файла или объект, подобный пути, архив будет записан в этот файл.
  • Если это открытый файловый объект, архив будет записан в него. Объект должен быть открыт для записи в байтовом режиме.
  • Если аргумент target не указан (или равен None), источником должен быть каталог, а целевой файл будет иметь то же имя, что и источник, с добавленным расширением .pyz.

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

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

Необязательный аргумент 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 может быть именем файла или файловым объектом, открытым для чтения в байтовом режиме. Предполагается, что он находится в начале архива.

Примеры

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

$ 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())

Указание интерпретатора

Обратите внимание: если вы укажете интерпретатор, а затем распространите архив приложения, необходимо убедиться, что указанный интерпретатор переносим. Средство запуска 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»: для пользователей Python 3.5, например, строку shebang придётся изменить.

Как правило, используйте «/usr/bin/env python2» или «/usr/bin/env python3» в зависимости от того, для Python 2 или Python 3 написан ваш код.

Создание автономных приложений с помощью 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.

Ограничения

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

Формат архива ZIP-приложения Python

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

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

Таким образом, формат ZIP-приложения Python формально состоит из следующего:

  1. Необязательная строка shebang: символы b'#!', за которыми следует имя интерпретатора, а затем символ новой строки (b'\n'). Имя интерпретатора может быть любым именем, допустимым при обработке строк «shebang» в ОС или средством запуска Python в Windows. В Windows имя интерпретатора должно быть закодировано в UTF-8, а в POSIX — в кодировке sys.getfilesystemencoding().
  2. Стандартные данные ZIP-файла, создаваемые модулем zipfile. ZIP-файл должен содержать файл с именем __main__.py (в «корне» ZIP-файла, то есть не во вложенном каталоге). Данные ZIP-файла могут быть сжаты или не сжаты.

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

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

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/zipapp.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API