Сборка Python-проекта в автономное приложение
Основные инструменты для создания исполняемых файлов
Разработчики Python часто сталкиваются с задачей распространять свои программы в виде исполняемых файлов (.exe на Windows), чтобы пользователям не приходилось устанавливать интерпретатор. Существует несколько инструментов, каждый из которых подходит для разных сценариев. Наиболее популярным и универсальным решением является PyInstaller, который поддерживает множество платформ и гибко настраивается.
Как упаковать скрипт Python в один exe файл с помощью PyInstaller?
PyInstaller анализирует код, находит все зависимости и собирает их в папку или один исполняемый файл. Основные шаги:
- Установка:
pip install pyinstallerсоздание исполняемого файла python (создание исполняемого файла (exe) из python)
- Базовая команда для создания одного файла без консольного окна (для GUI приложений):
pyinstaller --onefile --windowed my_script.py - Добавление иконки:
pyinstaller --onefile --windowed --icon=app.ico my_script.py - Добавление дополнительных данных (например, файлов конфигурации):
pyinstaller --add-data "config.json;." --onefile my_script.py - Указание скрытых импортов, если PyInstaller не смог их обнаружить:
pyinstaller --hidden-import=pandas --hidden-import=numpy --onefile my_script.py
После выполнения команды в папке dist появится готовый исполняемый файл.
Типичные проблемы и их решение:
- Антивирус блокирует exe – используйте ключ
или подписывайте файл цифровой подписью.--uac-admin - Ошибка ModuleNotFoundError при запуске – добавьте недостающие модули через
или вручную укажите пути в .spec файле.--hidden-import - Большой размер exe – используйте виртуальное окружение с минимальным набором библиотек или сжимайте с помощью UPX:
pyinstaller --upx-dir=/path/to/upx --onefile script.py
PyInstaller подходит для большинства проектов, включая те, что используют Tkinter, PyQt, wxPython, и даже научные библиотеки. Если требуется тонкая настройка, создаётся файл спецификации .spec, который можно редактировать.
Как использовать cx_Freeze для создания exe?
cx_Freeze – альтернатива PyInstaller, которая требует явного описания через setup.py. Этот инструмент хорошо работает с большими проектами, где нужно контролировать каждый модуль. Пример минимального файла setup.py:
from cx_Freeze import setup, Executable
setup(
name="MyApp",
version="1.0",
description="Пример приложения",
executables=[Executable("my_script.py", base="Win32GUI")] # base="Win32GUI" для скрытия консоли
)
Сборка выполняется командой:
python setup.py build
cx_Freeze по умолчанию создаёт папку с файлами, но можно настроить упаковку в один архив.
Возможные сложности:
- Если используются сторонние модули с DLL, их нужно явно указывать в include_files.
- Для работы с PyQt5 может потребоваться добавить плагины через опцию include_files.
cx_Freeze выбирают, когда нужен предсказуемый результат и полный контроль над сборкой, особенно в корпоративной среде.
Как скомпилировать Python в exe через Nuitka?
Nuitka переводит Python код в C++, а затем компилирует его в исполняемый файл. Это даёт прирост производительности. Установка:
pip install nuitka. Базовая команда:
nuitka --standalone --onefile --windows-disable-console --enable-plugin=tk-inter my_script.py
Ключ --standalone собирает все зависимости, --onefile упаковывает в один exe.
Проблемы:
- Сборка занимает больше времени из-за компиляции.
- Может потребоваться C++ компилятор (MSVC, MinGW).
- Некоторый динамический код (eval, exec) не поддерживается.
Nuitka используют в проектах, критичных к скорости, или когда нужно защитить исходный код (компиляция затрудняет декомпиляцию).
Как создать exe с помощью py2exe для старых проектов?
py2exe – классический инструмент, который до сих пор применяется для поддержки устаревших приложений. Требует написания setup.py:
from distutils.core import setup
import py2exe
setup(
windows=[{"script": "my_script.py"}],
options={"py2exe": {"includes": ["sip", "PyQt4.QtCore"]}}
)
Команда:
python setup.py py2exe. Результат – папка dist.
Ограничения:
- Не поддерживает Python 3.10+ (последняя версия py2exe работает с Python 3.4–3.9).
- Редко обновляется, поэтому для новых проектов лучше выбирать PyInstaller или cx_Freeze.
py2exe подходит только для поддержки legacy кода, написанного для старых версий Python.
Расширенный пример: сборка многофайлового проекта с данными
Допустим, проект состоит из основного скрипта main.py, модуля utils.py и папки data с файлом config.json. Собираем с помощью PyInstaller:
pyinstaller --onefile --add-data "data/config.json;data" --add-data "utils.py;." main.py
При запуске exe файлы utils.py и config.json будут извлечены во временную папку. В коде нужно обращаться к ним через sys._MEIPASS:
import sys
import os
def resource_path(relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath('.'), relative_path)
config_path = resource_path('data/config.json')
Результат сборки: один exe файл размером около 15 МБ (зависит от библиотек).
Работа с .spec файлом для точной настройки
Вместо длинных параметров командной строки удобно править файл спецификации. Генерируем его:
pyinstaller --onefile --name MyApp main.py. Открываем MyApp.spec и редактируем блок Analysis:
a = Analysis(['main.py'],
pathex=[],
binaries=[],
datas=[('data/config.json', 'data'), ('utils.py', '.')],
hiddenimports=['pandas', 'numpy'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
После правки запускаем:
pyinstaller MyApp.spec
Этот подход позволяет легко добавлять сложные исключения и повторно использовать настройки.
Создание exe с иконкой и скрытием консоли
Для GUI приложений (например, на Tkinter) нужно скрыть окно командной строки. Команда:
pyinstaller --onefile --windowed --icon=app.ico tkinter_app.py
После сборки получаем tkinter_app.exe без консоли. Если требуется консоль для отладки, используйте --console (по умолчанию). Результат – размер файла около 10 МБ.
Обработка скрытых импортов на примере pandas и numpy
PyInstaller иногда не находит зависимые модули внутри библиотек. Решение – явное указание --hidden-import. Пример:
pyinstaller --onefile --hidden-import=pandas._libs.parsers --hidden-import=numpy.core._methods data_script.py
После сборки запускаем exe. Если ошибок нет, значит импорты найдены. В противном случае добавляем новые импорты из трассировки.
Уменьшение размера с помощью виртуального окружения
Чтобы исключить лишние библиотеки, создайте изолированное окружение и установите только необходимые пакеты:
python -m venv venv
venv\Scripts\activate
pip install pyinstaller
pip install requests # и другие нужные модули
pyinstaller --onefile my_script.py
Размер exe может уменьшиться с 50 МБ до 10 МБ, если убрать большие библиотеки типа tensorflow.
Результаты тестовых сборок
Тестовый скрипт hello.py с единственной строкой print('Hello'):
pyinstaller --onefile hello.py
Результат (среднее):
Размер exe: 6.2 МБ Время сборки: 12 секунд
Скрипт с импортами pandas и numpy (пустой DataFrame):
pyinstaller --onefile --hidden-import=pandas --hidden-import=numpy pandas_script.py
Размер exe: 85 МБ Время сборки: 45 секунд
Этот пример показывает, как библиотеки влияют на итоговый размер.