Превращаем код на 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-файл. Вывод должен совпасть с предыдущей проверкой.
Что появится | Зачем нужно | Передавать пользователю? |
|---|---|---|
| Готовое приложение: EXE и поддерживающие файлы, обычно в | Да, папку целиком |
| Промежуточные результаты и диагностика сборки | Нет |
| Описание параметров сборки | Не для запуска; сохраняйте при необходимости воспроизводить сборку |
Назначение этих файлов и ключи команд описаны в 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.
В Script Location выберите
app.py.Для первой проверки установите One Directory и Console Based.
В настройках проверьте каталог вывода; стандартный вариант у проекта —
output.Нажмите Convert .py to .exe и изучите журнал сборки.
Запустите полученное приложение в терминале с аргументом
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. Кроме добавления файла в сборку нужно правильно находить его при запуске.
Тип файла | Где искать |
|---|---|
Неизменяемый ресурс, включённый в сборку | Относительно |
Внешний файл рядом с готовым EXE | В упакованной программе — относительно |
Документ, переданный пользователем | По аргументу или через диалог выбора файла |
Новый отчёт или настройки | В отдельно выбранном доступном для записи каталоге, не в служебной распаковке |
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 не найдена | Используйте нужный интерпретатор с |
| Пакет в окружении, динамические импорты, журнал |
| Включён ли ресурс в сборку; не зависит ли путь от случайного текущего каталога |
Работает только рядом с исходниками | Не читает ли программа данные из папки проекта; перенесена ли вся сборка 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 на одинаковых входных файлах.
Проверьте ожидаемые 2 строки и 5 слов, затем пустой файл, кириллицу, пробелы в пути, отсутствующий файл и неправильную кодировку.
Запустите сборку из другого каталога и из перенесённой папки, не опираясь на исходники.
Испытайте её на целевой Windows без установленного Python, с обычными пользовательскими правами.
Для onedir передайте всю папку; для onefile проверьте доступность временного каталога и отдельных пользовательских данных.
Проверьте, что ошибки видимы, настройки сохраняются в постоянном месте, а лишние файлы и секреты не попали в выпуск.
Сохраните точные версии Python, PyInstaller, его hooks и зависимостей вместе с командой или spec-файлом. Состав окружения — часть воспроизводимой сборки. Исходники и рецепт сборки храните в Git; временные результаты — отдельно. Для работы с изменениями пригодится материал о практических командах Git.
Частые вопросы
Можно ли конвертировать Python в EXE онлайн?
Сборку можно организовать в контролируемой Windows-среде, а не только на своём компьютере. Но случайному сайту придётся передать исходники и файлы проекта; без проверки обработки данных и версий среды это плохая замена понятному процессу. Публичные онлайн-конвертеры в рамках статьи не проверялись.
Можно ли так собрать Python-игру?
Да, при совместимости используемых библиотек со сборщиком. Кроме кода придётся проверить изображения, звук, шрифты, нативные компоненты и относительные пути. Принцип тот же, что в примере с assets, но полноту игрового дистрибутива нужно проверять отдельным запуском.
Как уменьшить размер EXE?
Сначала выясните состав зависимостей и уберите ненужные импорты и ресурсы. Не исключайте модули наугад: программа может сломаться в редко используемой функции. --onefile меняет форму распространения, а не обещает минимальный размер. Универсального безопасного коэффициента сжатия нет.
Рабочий маршрут от скрипта до приложения
Начните с исправного скрипта и отдельного окружения. Соберите onedir, проверьте запуск вне каталога проекта и только затем выбирайте onefile, отключение консоли и дополнительные настройки. auto-py-to-exe упрощает ввод параметров, но не заменяет понимание ресурсов, зависимостей и ошибок.
Готовность результата проверяется не размером файла и не сообщением сборщика, а тем, может ли пользователь запустить приложение на целевой системе и получить правильный результат. Источник, рецепт сборки и тесты сохраняйте отдельно от распространяемого EXE.
Комментарии 0
Обсудите материал, задайте вопрос или дополните его своим опытом.
Комментарии доступны зарегистрированным пользователям. Почту нужно подтвердить один раз.
Начните обсуждение: задайте вопрос автору или поделитесь практическим опытом.