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. Для этого необходимо включить все зависимости приложения в архив вместе с кодом приложения.
Чтобы создать автономный архив, выполните следующие действия:
- Обычным образом создайте приложение в каталоге, чтобы у вас был каталог
myappс файлом__main__.pyи всем необходимым вспомогательным кодом приложения. -
Установите все зависимости приложения в каталог
myappс помощью pip:$ python -m pip install -r requirements.txt --target myapp
(предполагается, что требования проекта перечислены в файле
requirements.txt; если это не так, зависимости можно перечислить непосредственно в командной строке pip). -
Создайте пакет приложения с помощью команды:
$ 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 формально состоит из следующего:
- Необязательная строка shebang: символы
b'#!', за которыми следует имя интерпретатора, а затем символ новой строки (b'\n'). Имя интерпретатора может быть любым именем, допустимым при обработке строк «shebang» в ОС или средством запуска Python в Windows. В Windows имя интерпретатора должно быть закодировано в UTF-8, а в POSIX — в кодировкеsys.getfilesystemencoding(). - Стандартные данные 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