Перейти к содержимому

Превращаем код на Python в исполняемый EXE-файл

Опубликовано25.09.2026
Обновлено25.09.2026
Просмотры971
Время чтения15 мин.
Оглавление статьи
Сборка Python-программы в EXE позволяет запускать её в Windows без отдельной установки интерпретатора и библиотек. PyInstaller упаковывает код и зависимости в один файл или папку с исполняемым файлом. Для корректного запуска нужно учесть внешние файлы, динамические импорты и пути к ресурсам: не всё определяется автоматически. Сборку для Windows выполняют в этой же системе, а режим одного файла требует распаковки компонентов при запуске и может увеличивать время старта.
Превращаем код на Python в исполняемый EXE-файл

Чтобы превратить Python-скрипт в EXE для Windows, установите PyInstaller в окружение проекта и соберите приложение на Windows. Сначала используйте режим --onedir: он создаёт папку с исполняемым файлом и зависимостями. Когда этот вариант заработает, переходите к --onefile, если для распространения удобнее один файл.

Пользователю такой сборки не требуется отдельно устанавливать Python. Но упаковка не создаёт графический интерфейс, не исправляет ошибки программы и не гарантирует защиту исходников. Ниже — полный путь от небольшого скрипта до проверяемой сборки, настройки auto-py-to-exe и разбор проблем с файлами, библиотеками и консолью.

Условия примеров: команды предназначены для PowerShell в Windows, исходники — для Python 3.10+. Документация проверена 25 сентября 2026 года по PyInstaller 6.22.3. Исходный код протестирован на Python 3.13.5 в Linux; Windows-сборка, запуск EXE и графические интерфейсы в этой работе не выполнялись.

Что именно получается из Python-кода

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

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

EXE и установщик — разные вещи. Упакованная программа уже может запускаться, а создание ярлыков, выбор каталога установки и удаление приложения относятся к отдельному этапу распространения. Для первого выпуска часто достаточно архива с полной папкой сборки и инструкцией.

Подготовьте Windows и отдельное окружение

PyInstaller не является кросс-компилятором: обычная сборка из Linux создаёт Linux-приложение, а не Windows EXE. Для показанного маршрута используйте Windows-компьютер, виртуальную машину с Windows или Windows-среду сборки в CI. Запуск Linux Python внутри WSL сам по себе не меняет целевую платформу.

Выберите поддерживаемую версию Python и совместимые с ней зависимости. Разрядность интерпретатора и двоичных библиотек тоже имеет значение: сборку x64 не следует объявлять универсальной для любых процессоров и Windows. Проверяйте целевую конфигурацию отдельно.

Создайте каталог textstats, откройте в нём PowerShell и выполните:

py --version
py -m venv .venv
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install --upgrade pyinstaller
.\.venv\Scripts\python.exe -m PyInstaller --version

Если команда py отсутствует, но нужный интерпретатор доступен как python, используйте его для создания окружения. Дальше команды явно обращаются к .venv\Scripts\python.exe. Активировать окружение для этого не обязательно — такой способ предусмотрен документацией venv и не требует менять политику запуска PowerShell-скриптов.

Если у вашего приложения есть зависимости, установите их в это же окружение до сборки. Файл requirements.txt нужно использовать только тогда, когда он действительно есть в проекте. В учебном примере ниже достаточно стандартной библиотеки. Основы окружений, модулей и исключений разобраны в путеводителе по Python для разработчика.

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

Подготовим скрипт, который легко проверить

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

Сохраните в app.py:

import argparse
import sys
from pathlib import Path


def summarize(path: Path) -> tuple[int, int]:
    text = path.read_text(encoding="utf-8-sig")
    return len(text.splitlines()), len(text.split())


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        description="Count lines and whitespace-separated words in UTF-8 text."
    )
    parser.add_argument("file", type=Path, help="path to a UTF-8 text file")
    args = parser.parse_args(argv)

    try:
        lines, words = summarize(args.file)
    except (OSError, UnicodeError) as error:
        print(f"Cannot read file: {error}", file=sys.stderr)
        return 1

    print(f"Lines: {lines}\nWords: {words}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

argparse разбирает аргумент командной строки, а Path.read_text() читает текст с явно заданной кодировкой. Вариант utf-8-sig допускает UTF-8 как с BOM, так и без него. Ошибка чтения выводится в поток ошибок, после чего программа завершает работу с кодом 1. Эти API описаны в справке argparse и pathlib.

Рядом создайте tasks.txt в UTF-8:

Проверить сборку
Отправить отчёт коллеге

Сначала запустите исходник:

.\.venv\Scripts\python.exe .\app.py .\tasks.txt

Ожидаемый результат:

Lines: 2
Words: 5

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

Первая сборка через PyInstaller: папка с EXE

В том же каталоге выполните:

.\.venv\Scripts\python.exe -m PyInstaller --onedir --name TextStats .\app.py
.\dist\TextStats\TextStats.exe .\tasks.txt

--name задаёт имя результата, --onedir выбирает папку с приложением. Второй командой вы запускаете уже EXE, а не исходный Python-файл. Вывод должен совпасть с предыдущей проверкой.

Что появится

Зачем нужно

Передавать пользователю?

dist\TextStats\

Готовое приложение: EXE и поддерживающие файлы, обычно в _internal

Да, папку целиком

build\TextStats\

Промежуточные результаты и диагностика сборки

Нет

TextStats.spec

Описание параметров сборки

Не для запуска; сохраняйте при необходимости воспроизводить сборку

Назначение этих файлов и ключи команд описаны в Using PyInstaller. Если скопировать из режима onedir только EXE, он может не найти интерпретатор или библиотеки. Архивируйте весь каталог dist\TextStats, не удаляя файлы, которые кажутся непонятными.

Первая проверка переноса: скопируйте полную папку сборки в другое место и запустите оттуда, передав полный путь к tasks.txt. Затем повторите запуск с другим текущим каталогом. Это помогает обнаружить неявную зависимость от папки проекта ещё до отправки программы коллеге.

Как собрать один EXE: режим onefile

Когда папочный вариант работает, соберите отдельную версию:

.\.venv\Scripts\python.exe -m PyInstaller --onefile --name TextStatsOne .\app.py
.\dist\TextStatsOne.exe .\tasks.txt

Разные имена позволяют не перепутать результаты двух режимов. Теперь программа находится в dist\TextStatsOne.exe, но пользовательский tasks.txt всё ещё передаётся отдельно: мы не просили включать его в сборку.

Критерий

onedir

onefile

Что распространять

Папку с EXE и зависимостями

Один EXE плюс внешние пользовательские данные, если они нужны

Начальный запуск

Не требует распаковки встроенного набора файлов, как в onefile

Распаковывает необходимые файлы во временную папку

Диагностика

Проще увидеть состав сборки

Больше особенностей временного размещения

Когда выбирать

Первая сборка, отладка, более крупные приложения

Проверенная утилита, для которой удобство одного файла важнее

По описанию onefile, загрузчик создаёт временный каталог вида _MEI... и удаляет его после нормального завершения. Распаковка добавляет работу при запуске. Поэтому один файл не означает ни отсутствие временных файлов, ни ускорение программы, ни минимальный размер.

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

Auto-py-to-exe: те же возможности через интерфейс

auto-py-to-exe — графическая оболочка над PyInstaller, а не независимый компилятор. Она удобна для выбора параметров, но наследует ограничения сборщика. Установите её в окружение проекта:

.\.venv\Scripts\python.exe -m pip install auto-py-to-exe
.\.venv\Scripts\python.exe -m auto_py_to_exe

В имени устанавливаемого пакета используются дефисы, в имени Python-модуля — подчёркивания. Такой запуск также помогает избежать ситуации, когда команда auto-py-to-exe не находится в PATH.

  1. В Script Location выберите app.py.

  2. Для первой проверки установите One Directory и Console Based.

  3. В настройках проверьте каталог вывода; стандартный вариант у проекта — output.

  4. Нажмите Convert .py to .exe и изучите журнал сборки.

  5. Запустите полученное приложение в терминале с аргументом tasks.txt. После успешной проверки можно выбрать One File.

Сторонние библиотеки должны быть установлены в окружение до запуска оболочки. Дополнительные данные добавляются через Additional Files; точку назначения нужно согласовать с кодом, который читает ресурс. Если ошибка возникает внутри PyInstaller, менять только оболочку обычно недостаточно.

Как убрать консоль и не сломать программу

--windowed, он же --noconsole, не создаёт окна приложения. Он отключает консоль у программы, у которой уже есть графический интерфейс. Нашу текстовую утилиту так собирать не следует: её результат выводится в терминал.

Для отдельного опыта сохраните простой GUI в gui_app.py:

import tkinter as tk
from tkinter import ttk


def main() -> None:
    root = tk.Tk()
    root.title("Проверка GUI")
    ttk.Label(root, text="Приложение запущено", padding=20).pack()
    ttk.Button(root, text="Закрыть", command=root.destroy).pack(pady=10)
    root.mainloop()


if __name__ == "__main__":
    main()

Сначала проверьте этот файл через Python в графической среде Windows, затем соберите:

.\.venv\Scripts\python.exe .\gui_app.py
.\.venv\Scripts\python.exe -m PyInstaller --onedir --windowed --name GuiDemo .\gui_app.py

Если приложение не появляется, пересоберите его без --windowed и запустите из терминала. В Windows-режиме без консоли sys.stdin, sys.stdout и sys.stderr могут быть None; полагаться на input() или обычный вывод диагностик нельзя. Это отдельно разобрано в описании ограничений оконной сборки.

Для собственной иконки можно добавить --icon .\app.ico, предварительно подготовив настоящий ICO-файл. Иконка исполняемого файла и оформление окна — отдельные настройки; файл иконки не исправит ошибки интерфейса.

Как добавить файлы и правильно задать пути

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

Тип файла

Где искать

Неизменяемый ресурс, включённый в сборку

Относительно Path(__file__).resolve().parent, с учётом структуры ресурсов

Внешний файл рядом с готовым EXE

В упакованной программе — относительно Path(sys.executable).parent

Документ, переданный пользователем

По аргументу или через диалог выбора файла

Новый отчёт или настройки

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

Path.cwd() возвращает текущий рабочий каталог процесса, а не гарантированно папку EXE. В обычном Python-запуске sys.executable указывает на интерпретатор; в упакованном — на загрузчик приложения. Эти различия описаны в Run-time Information.

Отдельный пример с ресурсом

Создайте папку assets рядом со скриптами и файл assets\message.txt с текстом Resources found. Сохраните в resource_demo.py:

from pathlib import Path


def read_message() -> str:
    resource = Path(__file__).resolve().parent / "assets" / "message.txt"
    return resource.read_text(encoding="utf-8").strip()


if __name__ == "__main__":
    print(read_message())

Соберите ресурс в одноимённый каталог внутри приложения:

.\.venv\Scripts\python.exe -m PyInstaller --onefile --name ResourceDemo --add-data "assets:assets" .\resource_demo.py
.\dist\ResourceDemo.exe

Ожидаемый вывод — Resources found. В актуальном синтаксисе --add-data "SOURCE:DEST" двоеточие разделяет исходный путь и каталог назначения, в том числе в этом Windows-примере. У старых руководств встречается другой разделитель, поэтому сверяйте параметры с версией сборщика.

__file__ внутри современной сборки указывает на расположение модуля в пакете. Для такого ресурса не нужно начинать с ручной проверки sys._MEIPASS. Но этот приём не означает «сохранять всё рядом с __file__»: встроенные данные и пользовательские файлы выполняют разные роли.

Библиотеки, скрытые импорты и spec-файл

Обычные импорты сборщик анализирует автоматически. Но имя модуля, вычисленное во время выполнения и переданное в importlib.import_module(), может остаться незамеченным. В таком случае сначала выясните, какой модуль действительно не найден, и добавьте его через --hidden-import либо подходящий hook.

--hidden-import не устанавливает пакет. Если модуль отсутствует даже при обычном запуске исходника, сначала исправьте окружение. И наоборот: предупреждения сборщика об условных импортах не всегда означают неисправную программу. Порядок диагностики приведён в When Things Go Wrong.

Когда параметров стало много, сохраните их в .spec. Это исполняемое Python-описание сборки, а не конфигурация приложения для конечного пользователя. После проверки его можно использовать так:

.\.venv\Scripts\python.exe -m PyInstaller .\TextStats.spec

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

Почему EXE не запускается или сразу закрывается

Сначала откройте PowerShell, затем запустите EXE командой. Быстро исчезнувшая консоль может означать как ошибку, так и нормальное завершение короткой программы. Уже открытый терминал сохраняет сообщение на экране.

Симптом

Что проверить

Команда pyinstaller не найдена

Используйте нужный интерпретатор с -m PyInstaller; проверьте установку в этом окружении

ModuleNotFoundError

Пакет в окружении, динамические импорты, журнал build\TextStats\warn-TextStats.txt

FileNotFoundError

Включён ли ресурс в сборку; не зависит ли путь от случайного текущего каталога

Работает только рядом с исходниками

Не читает ли программа данные из папки проекта; перенесена ли вся сборка onedir

После windowed пропал результат

Есть ли у программы GUI и собственный способ сообщать об ошибках

На другом ПК отсутствует DLL или не подходит формат

Архитектуру, версию Windows, совместимость Python и нативных зависимостей; не скачивайте случайные DLL

Программа долго начинает работу

Распаковку onefile, загрузку библиотек и собственную инициализацию; сравнивайте на одном компьютере

При работе с multiprocessing проверьте необходимость multiprocessing.freeze_support() под защитой if __name__ == "__main__". У PyInstaller есть собственные требования к запуску дочерних процессов; это отдельный сценарий из документации Common Issues and Pitfalls, а не обязательная строка для каждой маленькой утилиты.

Антивирус, подпись и защита исходников

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

Предупреждение Microsoft Defender SmartScreen о неизвестном приложении и обнаружение вредоносного кода антивирусом — не одна проверка. Microsoft описывает SmartScreen как оценку репутации файла и издателя. Подпись помогает установить издателя, но не гарантирует отсутствие предупреждения у нового файла.

Не предлагайте пользователям отключить защиту ради запуска. Проверьте исходники, зависимости и происхождение сборки; при подозрении на ошибочное обнаружение используйте процедуру анализа поставщика защиты. Самостоятельно считать любой сигнал «ложным срабатыванием PyInstaller» нельзя.

Для распространяемой программы подготовьте понятное описание, версию и доверенный канал доставки. Подпись и контрольная сумма не доказывают отсутствие ошибок, а обновление библиотек не попадает в ранее собранный EXE само собой: новую версию нужно собрать и проверить заново.

Когда рассматривать Nuitka или py2exe

Для первого маршрута достаточно PyInstaller, а auto-py-to-exe даёт ему удобный интерфейс. Другие инструменты полезно рассматривать под конкретные требования, а не как последовательные этапы одной сборки.

Инструмент

Подход

Что учитывать

PyInstaller

Упаковка интерпретатора, кода и зависимостей

Проверка ресурсов, импортов и целевой платформы

auto-py-to-exe

Графическая настройка PyInstaller

Не устраняет ограничения самого сборщика

Nuitka

Компиляция с использованием C-компилятора

Для распространения без установленного Python нужен соответствующий режим standalone или onefile

py2exe

Сборка Windows-приложений

Проверяйте поддерживаемый Python и современный API проекта

У Nuitka режим по умолчанию не равнозначен самостоятельному дистрибутиву. Сравнение скорости или размера требует измерений именно вашего приложения; в этом руководстве такие сравнительные тесты не проводились.

Современный py2exe не ограничен Python 3.4: журнал проекта описывает поддержку актуальных веток Python 3. Старый интерфейс build_exe удалён, вместо него используется py2exe.freeze. Возвращаться к устаревшему Python ради команды из старой статьи не нужно.

Что проверить перед передачей программы

Появление файла в dist подтверждает завершение сборки, но не работоспособность всех сценариев. Для нашей утилиты сравните исходник и EXE на одинаковых входных файлах.

  1. Проверьте ожидаемые 2 строки и 5 слов, затем пустой файл, кириллицу, пробелы в пути, отсутствующий файл и неправильную кодировку.

  2. Запустите сборку из другого каталога и из перенесённой папки, не опираясь на исходники.

  3. Испытайте её на целевой Windows без установленного Python, с обычными пользовательскими правами.

  4. Для onedir передайте всю папку; для onefile проверьте доступность временного каталога и отдельных пользовательских данных.

  5. Проверьте, что ошибки видимы, настройки сохраняются в постоянном месте, а лишние файлы и секреты не попали в выпуск.

Сохраните точные версии Python, PyInstaller, его hooks и зависимостей вместе с командой или spec-файлом. Состав окружения — часть воспроизводимой сборки. Исходники и рецепт сборки храните в Git; временные результаты — отдельно. Для работы с изменениями пригодится материал о практических командах Git.

Частые вопросы

Можно ли конвертировать Python в EXE онлайн?

Сборку можно организовать в контролируемой Windows-среде, а не только на своём компьютере. Но случайному сайту придётся передать исходники и файлы проекта; без проверки обработки данных и версий среды это плохая замена понятному процессу. Публичные онлайн-конвертеры в рамках статьи не проверялись.

Можно ли так собрать Python-игру?

Да, при совместимости используемых библиотек со сборщиком. Кроме кода придётся проверить изображения, звук, шрифты, нативные компоненты и относительные пути. Принцип тот же, что в примере с assets, но полноту игрового дистрибутива нужно проверять отдельным запуском.

Как уменьшить размер EXE?

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

Рабочий маршрут от скрипта до приложения

Начните с исправного скрипта и отдельного окружения. Соберите onedir, проверьте запуск вне каталога проекта и только затем выбирайте onefile, отключение консоли и дополнительные настройки. auto-py-to-exe упрощает ввод параметров, но не заменяет понимание ресурсов, зависимостей и ошибок.

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

Редакционная проверкаРедакция ИзмерьВебМатериал сверен редакцией: проверяем факты, актуальность условий и пользу для читателя.

Комментарии 0

Обсудите материал, задайте вопрос или дополните его своим опытом.

Присоединитесь к обсуждению

Комментарии доступны зарегистрированным пользователям. Почту нужно подтвердить один раз.

Пока нет комментариев

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