Содержание страницы
28.4. zipapp – Управление исполняемыми zip-архивами Python¶zipapp – 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.
28.4.1. Базовый пример¶Basic Example
В следующем примере показано, как с помощью интерфейса командной строки можно создать исполняемый архив из каталога с кодом Python. При запуске архив выполнит функцию main из модуля myapp.
$ python -m zipapp myapp -m "myapp:main"
$ python myapp.pyz
<output from myapp>
28.4.2. Интерфейс командной строки¶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нельзя указывать при копировании архива.
-
--info¶ Выводит интерпретатор, встроенный в архив, для диагностики. В этом случае все остальные опции игнорируются, а SOURCE должен быть архивом, а не каталогом.
-
-h,--help¶ Выводит краткую справку и завершает работу.
28.4.3. Python API¶
Модуль определяет две вспомогательные функции:
-
zipapp.create_archive(source, target=None, interpreter=None, main=None)¶ Создаёт архив приложения из source. Источником может быть любой из перечисленных вариантов:
- Имя каталога или объект
pathlib.Path, ссылающийся на каталог; в этом случае из содержимого этого каталога будет создан новый архив приложения. - Имя существующего файла архива приложения или объект
pathlib.Path, ссылающийся на такой файл; в этом случае файл копируется в целевой объект (с изменением для отражения значения, указанного для аргумента interpreter). Имя файла должно включать расширение.pyz, если это необходимо. - Файловый объект, открытый для чтения в байтовом режиме. Содержимое файла должно быть архивом приложения, и предполагается, что файловый объект находится в начале архива.
Аргумент target определяет, куда будет записан результирующий архив:
- Если это имя файла или объект
pathlb.Path, архив будет записан в этот файл. - Если это открытый файловый объект, архив будет записан в этот файловый объект, который должен быть открыт для записи в байтовом режиме.
- Если цель опущена (или
None), источник должен быть каталогом, и целью будет файл с тем же именем, что и источник, с\добавленным расширением.pyz.
Аргумент interpreter задаёт имя интерпретатора Python, с которым будет выполняться архив. Он записывается в виде строки «shebang» в начале архива. На POSIX эта строка будет интерпретироваться ОС, а на Windows – обрабатываться загрузчиком Python. Если опустить interpreter, строка shebang не записывается. Если интерпретатор указан, а целью является имя файла, то устанавливается бит исполняемости целевого файла.
Аргумент main задаёт имя вызываемого объекта, который будет использоваться как главная программа архива. Его можно указать только в том случае, если источник – каталог и в нём ещё нет файла
__main__.py. Аргумент main должен иметь форму «pkg.module:callable», и архив будет выполняться путём импорта «pkg.module» и вызова указанного вызываемого объекта без аргументов. Будет ошибкой опустить main, если источник – каталог и не содержит файла__main__.py, так как иначе полученный архив не будет исполняемым.Если для source или target указан файловый объект, вызывающая сторона обязана закрыть его после вызова create_archive.
При копировании существующего архива предоставленные файловые объекты должны иметь только методы
readиreadlineилиwrite. При создании архива из каталога, если цель – файловый объект, он будет передан классуzipfile.ZipFileи должен предоставлять методы, необходимые этому классу.- Имя каталога или объект
-
zipapp.get_interpreter(archive)¶ Возвращает интерпретатор, указанный в строке
#!в начале архива. Если строка#!отсутствует, возвращаетNone. Аргумент archive может быть именем файла или файлоподобным объектом, открытым для чтения в байтовом режиме. Предполагается, что он находится в начале архива.
28.4.4. Примеры¶Examples
Упаковывает каталог в архив и запускает его.
$ python -m zipapp myapp
$ python myapp.pyz
<output from myapp>
То же самое можно сделать с помощью функции create_archive():
>>> import zipapp
>>> zipapp.create_archive('myapp.pyz', 'myapp')
Чтобы сделать приложение непосредственно исполняемым на 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», так как вам придётся изменить строку shebang для пользователей Python 3.5, например.
28.4.5. Формат архива приложений Python Zip¶The 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 определяется так:
- Необязательная строка шебанга, содержащая символы
b'#!', за которыми следует имя интерпретатора, а затем символ новой строки (b'\n'). Имя интерпретатора может быть любым, приемлемым для обработки шебанга в ОС или для загрузчика Python в Windows. На Windows интерпретатор должен быть закодирован в UTF-8, а на POSIX – вsys.getfilesystemencoding(). - Стандартные данные zip-файла, создаваемые модулем
zipfile. Содержимое zip-файла должно включать файл с именем__main__.py(который должен находиться в «корне» zip-файла, то есть не в подкаталоге). Данные zip-файла могут быть сжатыми или несжатыми.
Если архив приложения содержит строку шебанга, на POSIX-системах у него может быть установлен бит исполняемости, чтобы его можно было запускать напрямую.
Не требуется, чтобы архивы приложений создавались с помощью инструментов из этого модуля – модуль предоставляет удобные средства, но архивы указанного формата, созданные любым способом, принимаются Python.