Сборка Python проекта в один исполняемый файл: практические методы

Раздел: Python -> Создание EXE

Общие принципы создания исполняемого файла из Python скрипта

Преобразование Python кода в самостоятельный исполняемый файл (EXE) позволяет запускать приложение на компьютерах без установленного интерпретатора Python. Это востребовано при распространении утилит, игр или инструментов для пользователей, не знакомых с программированием. Рассмотрим несколько подходов, каждый из которых имеет свои особенности.

Как собрать Python скрипт в один файл EXE с помощью PyInstaller?

PyInstaller - самый популярный инструмент для этой задачи. Он анализирует зависимости, упаковывает их вместе с вашим кодом и создаёт самодостаточный EXE файл.

pip install pyinstaller

компиляция кода python (компиляция кода python)

Базовая команда для сборки:

pyinstaller --onefile my_script.py

Python compile py (компиляция python кода)

После выполнения в папке dist появится файл my_script.exe.

Типичная ошибка:

Если скрипт использует неявно импортируемые модули (например, через importlib), PyInstaller может их пропустить. Решение - указать их явно:

pyinstaller --onefile --hidden-import=my_missing_module my_script.py

Python to c to exe (конвертация python в c и в exe)

Для скрытия консольного окна (GUI приложения) требуется флаг --noconsole:

pyinstaller --onefile --noconsole my_app.py

Добавление иконки:

pyinstaller --onefile --icon=logo.ico my_script.py

Как создать EXE с помощью cx_Freeze?

cx_Freeze - ещё один проверенный инструмент. Он требует создания файла setup.py с описанием проекта.

# setup.py
from cx_Freeze import setup, Executable

setup(
    name="MyApp",
    version="1.0",
    description="Example app",
    executables=[Executable("my_script.py", base="Win32GUI")]
)

Сборка выполняется командой:

python setup.py build

Итоговые файлы появятся в папке build. Для создания одного EXE без библиотек рядом - потребуется дополнительная настройка (вручную или через опцию includes).

Возможная проблема:

Работа с внешними DLL (например, tkinter) может потребовать указания путей вручную.

Как применить Nuitka для компиляции Python в нативный код и получить EXE?

Nuitka транслирует Python код в C++, затем компилирует его с помощью компилятора C (например, MinGW или Visual Studio). Результат - бинарник, часто работающий быстрее оригинала.

pip install nuitka
nuitka --mingw64 --onefile my_script.py

Флаг --onefile создаёт один EXE. Если нужен запуск без консоли - добавьте --windows-disable-console.

Ошибка компиляции:

Nuitka требует установленный компилятор C. В Windows удобно использовать mingw-w64. При отсутствии появится сообщение об ошибке: "gcc not found".

Как преобразовать Python скрипт в EXE используя py2exe?

py2exe - старый, но иногда полезный инструмент. Работает только с Python 3.4-3.8 (для старых версий). Требуется setup.py.

# setup.py (py2exe)
from distutils.core import setup
import py2exe

setup(
    console=["my_script.py"],
    options={
        "py2exe": {
            "bundle_files": 1,  # 1 - все в один EXE
            "compressed": True
        }
    },
    zipfile=None
)

Запуск:

python setup.py py2exe

Есть ограничения по поддержке современных библиотек и версий Python.

Проблема:

py2exe не поддерживает Python выше 3.8. Для новых проектов лучше использовать PyInstaller или Nuitka.

Как создать EXE без кода с помощью GUI утилиты auto-py-to-exe?

auto-py-to-exe - надстройка над PyInstaller с веб-интерфейсом. Установка и запуск:

pip install auto-py-to-exe
auto-py-to-exe

Откроется браузер, где можно выбрать скрипт, настроить опции (onefile, иконка, скрыть консоль) и запустить сборку одной кнопкой. Подходит для новичков.

Возможная ошибка:

Путь к скрипту не должен содержать кириллицу - это может вызвать проблемы при анализе зависимостей.

Как получить самодостаточный бинарник с PyOxidizer?

PyOxidizer создаёт исполняемый файл, встроив Python интерпретатор и все библиотеки внутрь. Требуется конфигурационный файл pyoxidizer.bzl.

# pyoxidizer.bzl (фрагмент)
def make_exe():
    return dist.default_binary_dist()

register_target("exe", make_exe)

Сборка:

pyoxidizer build

Инструмент поддерживает Python 3.7+. Он создаёт очень компактные бинарники, но требует изучения своего синтаксиса. Подходит для проектов с жёсткими требованиями к размеру.

Трудность:

PyOxidizer может не поддерживать все библиотеки Python, особенно с динамической загрузкой (C extensions).

Расширенные примеры и результаты

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

Пример
# tree.py
import sys
import os
from pathlib import Path

def resource_path(relative_path):
    """Получить путь к файлу, учитывая упаковку PyInstaller."""
    if getattr(sys, 'frozen', False):
        base_path = sys._MEIPASS
    else:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

# Использование
config_path = resource_path('config.ini')
with open(config_path) as f:
    print(f.read())
Пример
# Команда сборки с добавлением папки data
pyinstaller --onefile --add-data "data;data" tree.py

Результат: после запуска tree.exe он корректно находит config.ini внутри упакованного архива.

# Вывод (пример содержимого config.ini)
[APP]
version = 2.1
mode = production

Возможная ошибка при пропуске --add-data:

Без флага файл data/config.ini не будет скопирован в EXE, и приложение упадёт с ошибкой FileNotFoundError.

Пример 2: Nuitka с оптимизацией и замером производительности

Пример
# test_speed.py
import time

def heavy_function():
    total = 0
    for i in range(10_000_000):
        total += i * i
    return total

start = time.perf_counter()
result = heavy_function()
end = time.perf_counter()
print(f"Result: {result}")
print(f"Time: {end - start:.3f} sec")
Пример
# Команда компиляции
nuitka --mingw64 --onefile --lto=yes test_speed.py
# Результат (среднее время):
Python interpreter: ~2.1 sec
Nuitka compiled EXE: ~1.3 sec (ускорение ~40%)

Опция --lto=yes включает Link Time Optimization для лучшей производительности.

Пример 3: cx_Freeze с указанием включения модулей для работы с OpenCV (cv2)

Пример
# setup_opencv.py
from cx_Freeze import setup, Executable

build_exe_options = {
    "packages": ["cv2", "numpy"],
    "excludes": ["tkinter", "PyQt5"]  # исключить ненужное
}

setup(
    name="CVApp",
    version="1.0",
    options={"build_exe": build_exe_options},
    executables=[Executable("image_processor.py")]
)

Сборка: python setup_opencv.py build

Пример 4: py2exe для старого скрипта на Python 3.6

Пример
# legacy_setup.py
from distutils.core import setup
import py2exe
import sys

# Если нет консольного окна
sys.argv.append('py2exe')

setup(
    options = {
        "py2exe": {
            "bundle_files": 1,
            "compressed": True,
            "includes": ["json", "os"]
        }
    },
    console=["legacy_script.py"],
    zipfile = None,
)

Запуск: python legacy_setup.py

# Успешная сборка: в папке dist появится legacy_script.exe размером ~15 MB

Пример 5: auto-py-to-exe с нестандартным портом и автоматическим открытием

Пример
# Запуск с изменённым портом (по умолчанию 8080)
auto-py-to-exe --port 9090

После открытия браузера выберите скрипт, укажите параметры и нажмите "Convert .py to .exe". Для консольных приложений отметьте "Console Based".

Пример 6: PyOxidizer с явным указанием зависимостей (для проекта с requests)

Пример
# pyoxidizer.bzl (полный файл)
def make_exe():
    dist = default_python_distribution()
    policy = dist.make_python_packaging_policy()
    policy.allow_embedding = True
    exe = dist.to_python_executable(
        name="myapp",
        packaging_policy=policy,
    )
    exe.add_python_resources(exe.pip_install(["requests"]))
    exe.add_python_resources(exe.read_package_root(
        path="src",
        packages=["myapp"],
    ))
    return exe

register_target("exe", make_exe, default=True)

Сборка: pyoxidizer build --release

# Результат: бинарник ~10 MB (существенно меньше, чем у PyInstaller)

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

Компиляция кода Python - comments

En
компиляция кода python (python)