Python в exe: как собрать программу через PyInstaller и Nuitka

Чтобы сделать exe из Python-скрипта, хватит PyInstaller и команды pyinstaller --onefile.

Показываем сборку им и компилятором Nuitka, сравниваем размер и скорость запуска на одном скрипте и разбираем ошибки, из-за которых готовый exe падает, хотя сам скрипт работал.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 3090 статей автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3744 экспертных мнения Подписаться на Телеграм-канал
Обложка: Python в exe: как собрать программу через PyInstaller и Nuitka

Чтобы сделать exe из Python-скрипта, установите PyInstaller командой pip install pyinstaller и выполните pyinstaller --onefile script.py. Через несколько секунд в папке dist появится script.exe, и он запустится на компьютере, где Python не установлен. Если нужен быстрый старт и файл поменьше, соберите программу компилятором Nuitka: python -m nuitka --mode=onefile script.py.

Собирайте exe на Windows. PyInstaller по своей документации не кросс-компилятор: чтобы получить программу для Windows, его запускают на Windows. Если Python ещё не стоит, начните с инструкции как скачать и установить Python. А если язык только осваиваете, посмотрите онлайн-курсы по Python с ценами и программами.

Мы прогнали оба инструмента на одних и тех же скриптах. Ниже команды, вывод из терминала и ошибки, из-за которых готовый exe падает, хотя сам скрипт работал.

CheckroiCheckroiПодборка курсов по Python568 курсов • 51 школаСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

PyInstaller или Nuitka: что выбрать

Рой упаковывает программу в коробку с ярлыком exe

Это два разных подхода. PyInstaller ничего не компилирует в машинный код: он кладёт в один пакет интерпретатор, байт-код ваших модулей (файлы .pyc) и библиотеки, так описан его принцип работы. Nuitka переводит модули Python в программу на C и собирает её компилятором C.

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

Инструмент Что делает Команда Когда брать
PyInstaller упаковывает интерпретатор, байт-код и библиотеки pyinstaller --onefile app.py первый exe, утилиты, скрипты для коллег
Nuitka переводит код в C и компилирует python -m nuitka --mode=onefile app.py важен старт программы и размер файла
auto-py-to-exe окно с настройками поверх PyInstaller python -m auto_py_to_exe не хочется запоминать флаги

Есть и другие упаковщики, например cx_Freeze и py2exe. Для первой сборки они ничего не добавят: PyInstaller и Nuitka закрывают обе задачи, упаковку и компиляцию.

Как сделать exe через PyInstaller

Возьмём короткий скрипт hello.py, который спрашивает имя:

name = input("Как вас зовут? ")
print(f"Привет, {name}!")
  1. Создайте виртуальное окружение в папке проекта и активируйте его. В exe попадёт только то, что установлено в окружении, поэтому файл не распухнет от лишних пакетов. Как это сделать, показано в инструкции про venv.
  2. Установите упаковщик: pip install pyinstaller.
  3. Откройте командную строку в папке со скриптом. Если не знаете как, загляните в разбор запуска Python-скрипта через командную строку.
  4. Выполните pyinstaller --onefile hello.py.
  5. Заберите готовый файл из папки dist: на Windows это dist\hello.exe.

Рядом появятся папка build со служебными файлами и hello.spec. В spec-файле записана большая часть настроек сборки. Если вы его поправили, то по документации дальше передавайте PyInstaller его вместо скрипта: pyinstaller hello.spec.

У нас сборка заняла около 5 секунд, а файл весил 8 МБ. Запуск выглядит так:

Как вас зовут? Ваня
Привет, Ваня!

Один файл или папка

Без флага --onefile PyInstaller собирает папку: exe и рядом все библиотеки. У каждого варианта своя цена.

  • Один файл удобно отправить. Но при каждом запуске он распаковывает себя во временную папку _MEIxxxxxx, поэтому стартует медленнее.
  • Папка запускается мгновенно, её проще отлаживать: видно, какие файлы попали в сборку. Документация советует сначала добиться работы в режиме папки и только потом собирать один файл.

Если нужна сборка мышкой, поставьте пакет auto-py-to-exe через pip и запустите командой python -m auto_py_to_exe. Откроется окно с настройками, где скрипт, иконку и режим сборки выбирают мышкой.

Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Как скомпилировать Python через Nuitka

Nuitka нужен компилятор C. На Windows руководство Nuitka называет Visual Studio 2022 или новее; MinGW64 из коробки с Python 3.13 и новее не работает. На macOS хватает clang из инструментов разработчика Xcode.

  1. Установите пакет: python -m pip install nuitka.
  2. Проверьте, что скрипт работает обычным запуском python hello.py.
  3. Соберите один файл: python -m nuitka --mode=onefile hello.py. Старая форма --onefile тоже работает.
  4. Готовый hello.exe появится рядом со скриптом, а не в отдельной папке.

Первая сборка у нас шла 47 секунд: в неё вошла загрузка ccache, инструмента, который запоминает скомпилированные файлы. Повторная заняла 7,6 секунды, потому что готовые файлы берутся из кеша. Последние строки вывода:

Nuitka: Created binary that runs on macOS 26.0 (arm64) or higher.
Nuitka: Successfully created 'hello.bin'.

На Mac файл получает расширение .bin, на Windows Nuitka делает .exe. Флаги, которые пригодятся почти сразу:

  • --mode=standalone собирает папку вместо одного файла;
  • --output-filename=имя задаёт имя программы;
  • --windows-icon-from-ico=icon.ico ставит иконку;
  • --windows-console-mode=disable убирает окно консоли у программы с графическим интерфейсом;
  • --remove-output удаляет папку сборки после компиляции.

Сравнение на одном скрипте: размер и скорость

Две коробки разного размера на весах и секундомер

Скрипт hello.py собран обоими инструментами на Mac с Python 3.14.7, PyInstaller 6.22.3 и Nuitka 4.3.1. Время запуска считали медианой по десяти прогонам, скорость счёта проверяли числом Фибоначчи fib(32), которое считает рекурсивная функция.

Показатель PyInstaller, один файл PyInstaller, папка Nuitka, один файл
Размер 8 МБ 20 МБ 3,9 МБ
Время сборки 4,7–5,1 с 4,1 с 47 с первый раз, 7,6 с повторно
Запуск программы 1,72 с 0,03 с 0,40 с
fib(32) 0,14–0,16 с не мерили 0,12 с

Обычный python bench.py считал то же число за 0,14 секунды. Выходит, в нашем замере код почти не ускорился: Nuitka выиграла около 15 % на чистой арифметике. Её плюс в другом: файл вдвое меньше, а запускается в четыре раза быстрее, чем один файл PyInstaller.

На Windows абсолютные цифры будут другими, мы их не снимали. Если программа медленно считает, ускорять придётся сам код: упаковщик здесь почти ничего не даст.

Как положить файлы данных внутрь exe

Типичная ситуация: скрипт работает, а exe падает. Программа открывает файл, который лежит рядом с ней, например настройки:

with open("data/config.txt", encoding="utf-8") as f:
    print(f.read().strip())

Даже если добавить папку в сборку флагом --add-data, такой exe, запущенный из другой папки, ломается:

Traceback (most recent call last):
  File "app_naive.py", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'data/config.txt'
[PYI-40704:ERROR] Failed to execute script 'app_naive' due to unhandled exception!

Причина: относительный путь считается от текущей папки, а файлы сборки лежат во временной папке распаковки.

Решение: строить путь от __file__. С версии 4.3 PyInstaller указывает в этой переменной путь внутри сборки, а в Nuitka, как показал наш прогон, этот путь тоже работает. Один и тот же код работает и в обычном запуске, и в exe:

from pathlib import Path

BASE = Path(__file__).parent
print((BASE / "data" / "config.txt").read_text(encoding="utf-8").strip())

Команды сборки с папкой data:

pyinstaller --onefile --add-data "data:data" app.py
python -m nuitka --mode=onefile --include-data-dir=data=data app.py

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

Как собрать exe с внешними библиотеками

Библиотеки вроде requests PyInstaller находит сам: видит импорт и кладёт пакет в сборку вместе с зависимостями. Ловушка в другом: он берёт библиотеки из того Python, которым запущен.

Скрипт с одним запросом через requests мы упаковали дважды:

  • из окружения, где requests установлен: exe весит 11 МБ против 8 МБ у скрипта без библиотек и печатает «Статус ответа: 200»;
  • из окружения без requests: сборка закончилась строкой «Build complete!», а exe упал на первой же строке кода.
ModuleNotFoundError: No module named 'requests'
[PYI-45720:ERROR] Failed to execute script 'weather' due to unhandled exception!

Предупреждение при этом было, но только в файле build/weather/warn-weather.txt: «missing module named requests». Сообщения о ненайденных модулях PyInstaller в консоль не выводит, потому что их обычно много.

Решение: перед сборкой активируйте виртуальное окружение проекта, запустите скрипт обычным python из того же окна и только потом вызывайте pyinstaller. Если скрипт работает, библиотеки на месте и попадут в exe.

Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Иконка, имя и версия программы

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

Что задать PyInstaller Nuitka
Имя файла --name calc --output-filename=calc
Иконку --icon app.ico --windows-icon-from-ico=app.ico
Версию в свойствах файла --version-file version.txt --file-version=1.0.0 и --product-name=Calc

У PyInstaller иконка для Windows должна быть в формате .ico. Справка по флагам уточняет: картинку в другом формате он попробует перевести сам, если установлена библиотека Pillow.

Файл версии для PyInstaller проще не писать с нуля. Утилита pyi-grab_version вытаскивает описание версии из любого готового exe, его остаётся поправить под свою программу. В Nuitka версия задаётся прямо флагами, номер состоит максимум из четырёх чисел: 1.0 или 1.0.0.0.

Частые ошибки и что с ними делать

Рой радуется, когда собранная программа запустилась без ошибок

ModuleNotFoundError в готовом exe

PyInstaller ищет импорты по тексту кода. Модуль, который загружается по имени из строки через importlib.import_module("report"), он не видит:

ModuleNotFoundError: No module named 'report'
[PYI-43026:ERROR] Failed to execute script 'plugin' due to unhandled exception!

Решение: перечислить такие модули флагом --hidden-import report. После пересборки наш пример напечатал «Отчёт готов». Раздел документации о проблемах сборки подсказывает, где искать список пропущенных модулей: в файле build/имя/warn-имя.txt.

Окно консоли закрывается сразу

Консольная программа, запущенная двойным щелчком, получает своё окно, и оно закрывается вместе с программой. Если в конце скрипта нет ожидания, вывод мелькнёт и пропадёт. Добавьте в конец input("Нажмите Enter, чтобы выйти") или запускайте exe из открытой командной строки.

Лишнее чёрное окно у программы с интерфейсом

Для программы на tkinter или PyQt окно консоли не нужно. В PyInstaller его убирает флаг --windowed (он же --noconsole), в Nuitka — --windows-console-mode=disable.

Exe долго запускается

Один файл PyInstaller при каждом старте распаковывает всё содержимое во временную папку. В нашем замере это 1,7 секунды против 0,03 у сборки папкой.

Решение: соберите папку без --onefile и раздавайте её архивом или установщиком. Если нужен именно один файл, попробуйте Nuitka: у нас тот же скрипт стартовал за 0,4 секунды.

Антивирус удаляет сборку

Бывает, что антивирус удаляет файлы прямо во время сборки. Для этого случая в auto-py-to-exe есть флаг --build-directory-override: он переносит сборку в папку, которую можно внести в исключения антивируса.

Exe, собранный на Mac, не запускается на Windows

Это ожидаемо: на Mac получается программа для macOS. Для Windows соберите exe на Windows, в виртуальной машине или на сборочном сервере.

Можно ли вернуть код из exe

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

У Nuitka в exe лежит машинный код, собранный из C, и восстановить из него исходник на Python сложнее. Но всё, что нужно программе, лежит внутри файла, поэтому пароли и ключи API в код не кладите ни при какой сборке. Храните их отдельно, например в переменных окружения.

Если упаковка нужна для игры, посмотрите финальную часть разбора как сделать игру на PyGame: там сборка exe показана на проекте с картинками и звуками.

Где освоить Python системно

Упаковка в exe идёт последним шагом, а до неё программу нужно написать. Если код пока собирается из примеров, курс даст порядок: синтаксис, работу с файлами и библиотеками, проверку домашних заданий.

Ниже курсы по Python с ценами и программами. Полный список с фильтрами есть в разделе курсы по Python, а настроить редактор под первый проект поможет инструкция как настроить VS Code для Python.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Профессия «Python-разработчик»
Перейти на сайт курса
SkillboxSkillbox157 335 ₽5987 ₽/мес.10 месяцевОбзор курса
Fullstack-разработчик на Python
Перейти на сайт курса
НетологияНетология137 000 ₽7125 ₽/мес.21 месяцОбзор курса
ДО Профессия Python-разработчик
Перейти на сайт курса
GeekBrainsGeekBrains149 001 ₽3167 ₽/мес.10 месяцевОбзор курса
Автоматизированное тестирование на Python
Перейти на сайт курса
SkillboxSkillbox122 226 ₽4108 ₽/мес.9 месяцевОбзор курса
Профессия Python-разработчик
Перейти на сайт курса
SkillFactorySkillFactory140 040 ₽4279 ₽/мес.10 месяцевОбзор курса

Больше программ — в полном каталоге курсов по Python

Часто задаваемые вопросы

Нужно ли ставить Python на компьютер, где запускают exe?

Нет. И PyInstaller, и Nuitka кладут в сборку всё, что нужно программе для запуска, поэтому exe работает на компьютере без Python. Ставить Python нужно только туда, где вы собираете программу.

Почему exe из Python весит несколько мегабайт?

Внутри лежит интерпретатор и библиотеки, а не только ваш код. В нашем замере скрипт из двух строк в PyInstaller занял 8 МБ, в Nuitka 3,9 МБ. Чем больше библиотек импортирует программа, тем тяжелее файл, поэтому собирайте exe из чистого виртуального окружения.

Как убрать чёрное окно консоли у exe?

В PyInstaller добавьте флаг --windowed (он же --noconsole), в Nuitka флаг --windows-console-mode=disable. Убирайте консоль только у программ с окнами: консольный скрипт без неё не покажет вывод.

Как поставить иконку на exe?

Подготовьте файл в формате .ico и соберите программу с флагом --icon app.ico в PyInstaller или --windows-icon-from-ico=app.ico в Nuitka. Картинку PNG PyInstaller попробует перевести в нужный формат сам, если установлена библиотека Pillow.

Можно ли собрать exe для Windows на Mac или Linux?

PyInstaller так не умеет: по документации программу для Windows собирают на Windows. Если основной компьютер на macOS или Linux, соберите exe в виртуальной машине с Windows или на сборочном сервере.

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!