Использование PyInstaller для легкого распространения приложений на Python

Оглавление

Завидуете ли вы Go разработчикам, создающим исполняемый файл и легко отправляющим его пользователям? Разве не было бы здорово, если бы ваши пользователи могли запускать ваше приложение, ничего не устанавливая? Это мечта, и PyInstaller - один из способов достичь этого в экосистеме Python.

Существует бесчисленное множество руководств о том, как устанавливать виртуальные среды, управлять зависимостями, избегать ловушек зависимостей и публиковать в PyPI, что полезно при создании библиотек Python. Гораздо меньше информации для разработчиков, создающих Python-приложения. Это руководство предназначено для разработчиков, которые хотят распространять приложения среди пользователей, которые могут быть или не быть разработчиками Python.

В этом уроке вы узнаете следующее:

  • Как PyInstaller может упростить распространение приложений
  • Как использовать PyInstaller в собственных проектах
  • Как отладить ошибки PyInstaller
  • Что PyInstaller не умеет делать

PyInstaller дает вам возможность создать папку или исполняемый файл, который пользователи смогут сразу же запустить без дополнительной установки. Чтобы в полной мере оценить возможности PyInstaller, полезно вернуться к некоторым проблемам распространения, которых PyInstaller поможет вам избежать.

Проблемы распространения

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

Подумайте о том, что вы обычно делаете, когда настраиваете новую машину для разработки на Python. Вероятно, это происходит примерно так:

  • Скачайте и установите определенную версию Python
  • Настройте pip
  • Установите виртуальную среду
  • Получите копию вашего кода
  • Установите зависимости

Остановитесь на мгновение и подумайте, имеет ли смысл любой из описанных выше шагов, если вы не разработчик, тем более разработчик Python. Скорее всего, нет.

Эти проблемы взрываются, если вашему пользователю посчастливилось добраться до части установки, посвященной зависимостям. За последние несколько лет ситуация значительно улучшилась с распространением колес, но некоторые зависимости все еще требуют компиляторов C/C++ или даже FORTRAN!

Этот барьер для входа слишком высок, если ваша цель - сделать приложение доступным для как можно большего числа пользователей. Как часто говорит Раймонд Хеттингер в своих превосходных выступлениях, "Должен быть лучший способ"

PyInstaller

PyInstaller абстрагирует эти детали от пользователя, находя все ваши зависимости и собирая их вместе. Ваши пользователи даже не узнают, что они запускают Python-проект, потому что интерпретатор Python сам входит в состав вашего приложения. Прощайте сложные инструкции по установке!

PyInstaller выполняет этот удивительный подвиг, интроспектируя ваш Python-код, обнаруживая зависимости, а затем упаковывая их в подходящий формат в зависимости от вашей операционной системы.

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

Кроме того, PyInstaller может создавать исполняемые файлы для Windows, Linux или macOS. Это означает, что пользователи Windows получат .exe, пользователи Linux - обычный исполняемый файл, а пользователи macOS - пакет .app. Здесь есть некоторые оговорки. Дополнительные сведения см. в разделе ограничения.

Подготовка проекта

PyInstaller требует, чтобы ваше приложение соответствовало некоторой минимальной структуре, а именно, чтобы у вас был сценарий CLI для запуска вашего приложения. Часто это означает создание небольшого скрипта вне вашего пакета Python, который просто импортирует ваш пакет и запускает main().

Сценарий точки входа - это сценарий Python. Технически вы можете делать все, что хотите, в сценарии точки входа, но вам следует избегать использования явного относительного импорта. Вы можете использовать относительный импорт во всем остальном приложении, если это ваш предпочтительный стиль.

Примечание: Точка входа - это код, с которого начинается ваш проект или приложение.

Вы можете попробовать это в своем собственном проекте или следовать за проектом Real Python feed reader project. Более подробную информацию о проекте reader можно найти в руководстве Publishing a Package on PyPI.

Первым шагом к созданию исполняемой версии этого проекта является добавление скрипта точки входа. К счастью, проект feed reader хорошо структурирован, поэтому для его запуска достаточно создать короткий скрипт вне пакета. Например, вы можете создать файл под названием cli.py рядом с пакетом reader со следующим кодом:

from reader.__main__ import main

if __name__ == '__main__':
    main()

Этот cli.py скрипт вызывает main() для запуска программы чтения фидов.

При работе над собственным проектом создать скрипт с точкой входа несложно, поскольку вы знакомы с кодом. Однако найти точку входа в чужом коде не так просто. В этом случае вы можете начать с просмотра файла setup.py в стороннем проекте.

Ищите ссылку на аргумент entry_points в setup.py проекта. Например, вот setup.py проекта Reader:

setup(
    name="realpython-reader",
    version="1.0.0",
    description="Read the latest Real Python tutorials",
    long_description=README,
    long_description_content_type="text/markdown",
    url="https://github.com/realpython/reader",
    author="Real Python",
    author_email="info@realpython.com",
    license="MIT",
    classifiers=[
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python",
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 3",
    ],
    packages=["reader"],
    include_package_data=True,
    install_requires=[
        "feedparser", "html2text", "importlib_resources", "typing"
    ],
    entry_points={"console_scripts": ["realpython=reader.__main__:main"]},
)

Как видите, в точке входа cli.py скрипт вызывает ту же функцию, которая упоминается в аргументе entry_points.

После этого изменения каталог проекта читалки должен выглядеть следующим образом, при условии, что вы проверили его в папке с названием reader:

reader/
|
├── reader/
|   ├── __init__.py
|   ├── __main__.py
|   ├── config.cfg
|   ├── feed.py
|   └── viewer.py
|
├── cli.py
├── LICENSE
├── MANIFEST.in
├── README.md
├── setup.py
└── tests

Обратите внимание, что сам код программы чтения не изменился, просто появился новый файл с именем cli.py. Этот скрипт обычно является всем, что необходимо для использования вашего проекта с PyInstaller.

Однако вам также следует обратить внимание на использование __import__() или импорта внутри функций. В терминологии PyInstaller они называются скрытыми импортами.

Вы можете вручную указать скрытый импорт, чтобы заставить PyInstaller включить эти зависимости, если изменение импорта в вашем приложении слишком сложно. Вы увидите, как это сделать позже в этом руководстве.

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

Использование PyInstaller

Первым шагом будет установка PyInstaller из PyPI. Вы можете сделать это с помощью pip, как и другие пакеты для Python:

$ pip install pyinstaller

pip установит зависимости PyInstaller вместе с новой командой: pyinstaller. PyInstaller можно импортировать в ваш Python-код и использовать как библиотеку, но вы, скорее всего, будете использовать его только как CLI-инструмент.

Вы будете использовать интерфейс библиотеки, если создадите свои собственные hook-файлы.

Вы увеличите вероятность того, что PyInstaller по умолчанию создаст исполняемый файл, если у вас есть только чисто Python-зависимости. Однако не стоит слишком напрягаться, если у вас есть более сложные зависимости с расширениями C/C++.

PyInstaller поддерживает множество популярных пакетов, таких как NumPy, PyQt и Matplotlib, без какой-либо дополнительной работы с вашей стороны. Подробнее о списке пакетов, которые официально поддерживает PyInstaller, вы можете узнать в документации по PyInstaller.

Не беспокойтесь, если некоторые из ваших зависимостей не указаны в официальной документации. Многие пакеты Python прекрасно работают. На самом деле, PyInstaller настолько популярен, что во многих проектах есть объяснения, как заставить все работать с помощью PyInstaller.

Короче говоря, шансы на то, что ваш проект будет работать "из коробки", высоки.

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

Сначала cd в папке с вашей точкой входа и передайте ее в качестве аргумента команде pyinstaller, которая была добавлена в вашу PATH при установке PyInstaller.

Например, введите следующее после того, как вы cd войдете в каталог верхнего уровня reader, если вы следите за проектом по чтению фидов:

$ pyinstaller cli.py

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

Копание в артефактах PyInstaller

PyInstaller сложен под капотом и будет создавать много выходных данных. Поэтому важно знать, на чем сосредоточиться в первую очередь. А именно, на исполняемом файле, который вы можете распространять среди своих пользователей, и на потенциальной отладочной информации. По умолчанию команда pyinstaller создаст несколько интересных вещей:

  • A *.spec файл
  • A build/ папка
  • A dist/ папка

Файл спецификации

По умолчанию файл спецификации будет назван в честь вашего CLI-скрипта. Продолжая наш предыдущий пример, вы увидите файл с именем cli.spec. Вот как выглядит файл спецификации по умолчанию после запуска PyInstaller на файле cli.py:

# -*- mode: python -*-

block_cipher = None

a = Analysis(['cli.py'],
             pathex=['/Users/realpython/pyinstaller/reader'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='cli',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='cli')

Этот файл будет автоматически создан командой pyinstaller. В вашей версии пути будут отличаться, но большинство должно быть одинаковым.

Не волнуйтесь, вам не нужно понимать приведенный выше код, чтобы эффективно использовать PyInstaller!

Этот файл можно модифицировать и повторно использовать для создания исполняемых файлов в дальнейшем. Вы можете немного ускорить процесс сборки, предоставив этот файл спецификаций вместо скрипта входа в команду pyinstaller.

Существует несколько специфических случаев использования файлов спецификации PyInstaller. Однако для простых проектов вам не нужно будет беспокоиться об этих деталях, если только вы не хотите сильно настраивать то, как собирается ваш проект.

Папка сборки

Папка build/ - это место, куда PyInstaller помещает большинство метаданных и внутреннюю бухгалтерию для сборки вашего исполняемого файла. По умолчанию содержимое папки будет выглядеть примерно так:

build/
|
└── cli/
    ├── Analysis-00.toc
    ├── base_library.zip
    ├── COLLECT-00.toc
    ├── EXE-00.toc
    ├── PKG-00.pkg
    ├── PKG-00.toc
    ├── PYZ-00.pyz
    ├── PYZ-00.toc
    ├── warn-cli.txt
    └── xref-cli.html

Папка build может быть полезна для отладки, но если у вас нет проблем, эту папку можно игнорировать. Подробнее об отладке вы узнаете позже в этом учебнике.

Dist Folder

После сборки у вас будет папка dist/, похожая на следующую:

dist/
|
└── cli/
    └── cli

Папка dist/ содержит конечный артефакт, который вы хотите отправить своим пользователям. Внутри папки dist/ находится папка с именем вашей точки входа. Так, в этом примере у вас будет папка dist/cli, содержащая все зависимости и исполняемый файл для нашего приложения. Исполняемый файл для запуска - это dist/cli/cli или dist/cli/cli.exe, если вы работаете в Windows.

Вы также найдете множество файлов с расширением .so, .pyd и .dll в зависимости от вашей операционной системы. Это общие библиотеки, представляющие зависимости вашего проекта, которые PyInstaller создал и собрал.

Примечание: Вы можете добавить *.spec, build/ и dist/ в ваш .gitignore файл, чтобы сохранить git status в чистоте, если вы используете git для контроля версий. Файл gitignore GitHub по умолчанию для проектов Python уже делает это за вас.

Вы захотите распространить всю папку dist/cli, но вы можете переименовать cli в любое удобное для вас место.

На этом этапе вы можете попробовать запустить исполняемый файл dist/cli/cli, если вы следите за примером чтения фидов.

Вы заметите, что запуск исполняемого файла приводит к ошибкам с упоминанием файла version.txt. Это происходит потому, что для работы программы чтения фидов и ее зависимостей требуются дополнительные файлы данных, о которых PyInstaller не знает. Чтобы исправить это, вам придется указать PyInstaller на необходимость version.txt, о чем вы узнаете при тестировании вашего нового исполняемого файла.

Настройка сборки

PyInstaller поставляется с большим количеством опций, которые могут быть предоставлены в виде файлов спецификаций или обычных опций CLI. Ниже приведены некоторые из наиболее распространенных и полезных опций.

--name

Измените имя вашего исполняемого файла.

Это способ избежать того, чтобы папки с исполняемыми файлами, файлами спецификаций и артефактами сборки были названы в честь вашего скрипта точки входа. --name полезно, если у вас есть привычка называть свой сценарий точки входа чем-то вроде cli.py, как это делаю я.

Вы можете создать исполняемый файл с именем realpython из сценария cli.py с помощью следующей команды:

$ pyinstaller cli.py --name realpython

--onefile

Упакуйте все ваше приложение в один исполняемый файл.

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

Эта опция не принимает никаких аргументов. Чтобы собрать проект в один файл, можно выполнить сборку с помощью такой команды:

$ pyinstaller cli.py --onefile

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

--hidden-import

Перечислите несколько импортов верхнего уровня, которые PyInstaller не смог обнаружить автоматически.

Это один из способов обойтись без использования import внутри функций и __import__(). Вы также можете использовать --hidden-import несколько раз в одной команде.

Эта опция требует указания имени пакета, который вы хотите включить в исполняемый файл. Например, если ваш проект импортировал библиотеку requests внутри функции, то PyInstaller не будет автоматически включать requests в ваш исполняемый файл. Вы можете использовать следующую команду, чтобы заставить requests быть включенным:

$ pyinstaller cli.py --hiddenimport=requests

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

--add-data и --add-binary

Укажите PyInstaller вставить дополнительные данные или бинарные файлы в вашу сборку.

Это полезно, когда вы хотите добавить в пакет файлы конфигурации, примеры или другие данные, не относящиеся к коду. Пример этого вы увидите позже, если будете следить за проектом feed reader.

--exclude-module

Исключить включение некоторых модулей в исполняемый файл

Это полезно для исключения требований только для разработчиков, например, фреймворков для тестирования. Это отличный способ сделать артефакт, который вы предоставляете пользователям, как можно меньше. Например, если вы используете pytest, вы можете исключить это из вашего исполняемого файла:

$ pyinstaller cli.py --exclude-module=pytest

-w

Избегайте автоматического открытия окна консоли для stdout протоколирования.

Это полезно только в том случае, если вы создаете приложение с графическим интерфейсом. Это поможет вам скрыть детали вашей реализации, позволяя пользователям никогда не видеть терминал.

Аналогично опции --onefile, -w не принимает никаких аргументов:

$ pyinstaller cli.py -w

.spec file

Как уже упоминалось ранее, вы можете использовать автоматически сгенерированный файл .spec для дальнейшей настройки исполняемого файла. Файл .spec представляет собой обычный Python-скрипт, который неявно использует API библиотеки PyInstaller.

Поскольку это обычный Python-скрипт, внутри него можно делать практически все. Вы можете обратиться к официальной документации по PyInstaller Spec file для получения дополнительной информации об этом API.

Тестирование нового исполняемого файла

Лучший способ проверить новый исполняемый файл - это протестировать его на новой машине. На новой машине должна стоять та же ОС, что и на вашей машине для сборки. В идеале эта машина должна быть максимально похожа на ту, на которой работают ваши пользователи. Это не всегда возможно, поэтому следующим лучшим вариантом будет тестирование на собственной машине.

Главное - запустить полученный исполняемый файл без активированной среды разработки. Это означает запуск без virtualenv, conda или любого другого окружения, которое может получить доступ к вашей установке Python. Помните, что одна из главных целей исполняемого файла, созданного с помощью PyInstaller, заключается в том, чтобы пользователям не требовалось ничего устанавливать на своей машине.

Продолжая пример с программой чтения фидов, вы заметите, что запуск стандартного исполняемого файла cli в папке dist/cli не удается. К счастью, ошибка указывает вам на проблему:

FileNotFoundError: 'version.txt' resource not found in 'importlib_resources'
[15110] Failed to execute script cli

Для работы пакета importlib_resources требуется файл version.txt. Вы можете добавить этот файл в сборку с помощью опции --add-data. Вот пример включения необходимого файла version.txt:

$ pyinstaller cli.py \
    --add-data venv/reader/lib/python3.6/site-packages/importlib_resources/version.txt:importlib_resources

Эта команда указывает PyInstaller включить файл version.txt в папку importlib_resources в новую папку в вашей сборке под названием importlib_resources.

Примечание: В командах pyinstaller используется символ \, чтобы облегчить чтение команды. Вы можете опустить \ при самостоятельном выполнении команд или скопировать и вставить команды как есть, при условии, что вы используете те же пути.

Вам нужно будет изменить путь в приведенной выше команде, чтобы он соответствовал тому, куда вы установили зависимости feed reader.

Теперь запуск нового исполняемого файла приведет к новой ошибке о config.cfg файле.

Этот файл требуется проекту feed reader, поэтому вам нужно убедиться, что он включен в вашу сборку:

$ pyinstaller cli.py \
    --add-data venv/reader/lib/python3.6/site-packages/importlib_resources/version.txt:importlib_resources \
    --add-data reader/config.cfg:reader

Опять же, вам нужно будет изменить путь к файлу в зависимости от того, где у вас находится проект feed reader.

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

Отладка исполняемых файлов PyInstaller

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

Ниже приведены несколько распространенных стратегий, которые не идут в особом порядке. Часто одна из этих стратегий или их комбинация приводят к прорыву в сложных сеансах отладки.

Используйте терминал

Сначала попробуйте запустить исполняемый файл из терминала, чтобы вы могли видеть весь вывод.

Не забудьте снять флаг -w сборки, чтобы увидеть все stdout в окне консоли. Часто вы увидите ImportError исключения, если зависимость отсутствует.

Отладочные файлы

Осмотрите файл build/cli/warn-cli.txt на предмет наличия проблем. PyInstaller создает много вывода, чтобы помочь вам понять, что именно он создает. Копание в папке build/ - отличное место для начала.

Сборки в одном каталоге

Используйте режим распространения --onedir, когда вместо одного исполняемого файла создается папка с дистрибутивом. Опять же, это режим по умолчанию. Сборка с помощью --onedir дает возможность проверить все включенные зависимости, а не прятать все в одном исполняемом файле.

--onedir полезен для отладки, но --onefile обычно проще для пользователям понять. После отладки вы можете захотеть переключиться в режим --onefile для упрощения распространения.

Дополнительные параметры CLI

PyInstaller также имеет опции, позволяющие контролировать количество информации, выводимой в процессе сборки. Пересоберите исполняемый файл с помощью опции --log-level=DEBUG в PyInstaller и просмотрите вывод.

PyInstaller будет создавать много вывода при увеличении многословности с помощью --log-level=DEBUG. Полезно сохранить этот вывод в файл, к которому можно обратиться позже, вместо того чтобы прокручивать его в Терминале. Для этого вы можете использовать функцию перенаправления в вашей оболочке. Вот пример:

$ pyinstaller --log-level=DEBUG cli.py 2> build.txt

При использовании вышеуказанной команды у вас будет файл под названием build.txt, содержащий множество дополнительных DEBUG сообщений.

Примечание: Стандартное перенаправление с помощью > не является достаточным. PyInstaller печатает в поток stderr, не stdout. Это означает, что вам нужно перенаправить поток stderr в файл, что можно сделать с помощью 2, как в предыдущей команде.

Вот пример того, как может выглядеть ваш build.txt файл:

67 INFO: PyInstaller: 3.4
67 INFO: Python: 3.6.6
73 INFO: Platform: Darwin-18.2.0-x86_64-i386-64bit
74 INFO: wrote /Users/realpython/pyinstaller/reader/cli.spec
74 DEBUG: Testing for UPX ...
77 INFO: UPX is not available.
78 DEBUG: script: /Users/realptyhon/pyinstaller/reader/cli.py
78 INFO: Extending PYTHONPATH with paths
['/Users/realpython/pyinstaller/reader',
 '/Users/realpython/pyinstaller/reader']

В этом файле будет много подробной информации о том, что было включено в вашу сборку, почему что-то не было включено, и как был упакован исполняемый файл.

Вы также можете пересобрать исполняемый файл, используя опцию --debug в дополнение к опции --log-level для получения еще большей информации.

Примечание: Опции -y и --clean полезны при перестройке, особенно при первоначальной настройке сборок или сборке с Continuous Integration. Эти опции удаляют старые сборки и избавляют от необходимости вводить данные пользователем в процессе сборки.

Дополнительная документация по PyInstaller

Вики PyInstaller GitHub Wiki содержит множество полезных ссылок и советов по отладке. Наиболее заметными являются разделы о том, как убедиться, что все упаковано правильно и что делать если что-то идет не так.

Помощь в обнаружении зависимостей

Наиболее часто встречающаяся проблема - это ImportError исключения, если PyInstaller не смог правильно определить все ваши зависимости. Как уже говорилось, это может произойти, если вы используете __import__(), импорт внутри функций или другие типы скрытого импорта.

Многие из этих проблем можно решить с помощью опции --hidden-import PyInstaller CLI. Она указывает PyInstaller включить модуль или пакет, даже если он не обнаружил его автоматически. Это самый простой способ обойтись без динамической магии импорта в вашем приложении.

Другой способ обойти проблемы - hook-файлы. Эти файлы содержат дополнительную информацию, помогающую PyInstaller упаковать зависимость. Вы можете написать свои собственные хуки и указать PyInstaller использовать их с помощью опции --additional-hooks-dir CLI.

Файлы хуков - это то, как сам PyInstaller работает внутри, поэтому вы можете найти множество примеров файлов хуков в исходном коде PyInstaller.

Ограничения

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

PyInstaller поддерживает создание исполняемых файлов для Windows, Linux и macOS, но он не может кросс-компилировать. Таким образом, вы не можете создать исполняемый файл для одной операционной системы из другой операционной системы. Поэтому, чтобы распространять исполняемые файлы для нескольких типов ОС, вам понадобится машина сборки для каждой поддерживаемой ОС.

В связи с ограничением кросс-компиляции полезно знать, что PyInstaller технически не собирает в пакет абсолютно все, что нужно вашему приложению для работы. Ваш исполняемый файл по-прежнему зависит от пользовательских glibc. Как правило, вы можете обойти это ограничение glibc путем сборки на самой старой версии каждой ОС, на которую вы собираетесь ориентироваться.

Например, если вы хотите использовать широкий спектр Linux-машин, то можете построить на более старой версии CentOS. Это обеспечит совместимость с большинством версий, более новых, чем та, на которой вы собираете. Такая же стратегия описана в PEP 0513, и именно ее рекомендует PyPA для создания совместимых колес.

На самом деле, вы можете рассмотреть возможность использования докер-образа Manylinux от PyPA для среды сборки Linux. Вы можете начать с базового образа, затем установить PyInstaller вместе со всеми зависимостями и получить образ сборки, поддерживающий большинство вариантов Linux.

Заключение

PyInstaller поможет сделать ненужными сложные установочные документы. Вместо этого пользователи могут просто запустить ваш исполняемый файл, чтобы начать работу как можно быстрее. Рабочий процесс PyInstaller можно свести к следующим действиям:

  1. Создайте скрипт с точкой входа, вызывающий вашу главную функцию.
  2. Установите PyInstaller.
  3. Запустите PyInstaller на вашей точке входа.
  4. Протестируйте ваш новый исполняемый файл.
  5. Отправьте полученную папку dist/ пользователям.

Вашим пользователям не нужно знать, какую версию Python вы использовали или что ваше приложение вообще использует Python!

Вернуться на верх