Чтобы сделать 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 падает, хотя сам скрипт работал.
PyInstaller или Nuitka: что выбрать

Это два разных подхода. 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}!")
- Создайте виртуальное окружение в папке проекта и активируйте его. В exe попадёт только то, что установлено в окружении, поэтому файл не распухнет от лишних пакетов. Как это сделать, показано в инструкции про venv.
- Установите упаковщик:
pip install pyinstaller. - Откройте командную строку в папке со скриптом. Если не знаете как, загляните в разбор запуска Python-скрипта через командную строку.
- Выполните
pyinstaller --onefile hello.py. - Заберите готовый файл из папки
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. Откроется окно с настройками, где скрипт, иконку и режим сборки выбирают мышкой.
Как скомпилировать Python через Nuitka
Nuitka нужен компилятор C. На Windows руководство Nuitka называет Visual Studio 2022 или новее; MinGW64 из коробки с Python 3.13 и новее не работает. На macOS хватает clang из инструментов разработчика Xcode.
- Установите пакет:
python -m pip install nuitka. - Проверьте, что скрипт работает обычным запуском
python hello.py. - Соберите один файл:
python -m nuitka --mode=onefile hello.py. Старая форма--onefileтоже работает. - Готовый
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.
Иконка, имя и версия программы
По умолчанию 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-разработчик» Перейти на сайт курса | 157 335 ₽ | 5987 ₽/мес. | 10 месяцев | Обзор курса | |
| Fullstack-разработчик на Python Перейти на сайт курса | 137 000 ₽ | 7125 ₽/мес. | 21 месяц | Обзор курса | |
| ДО Профессия Python-разработчик Перейти на сайт курса | 149 001 ₽ | 3167 ₽/мес. | 10 месяцев | Обзор курса | |
| Автоматизированное тестирование на Python Перейти на сайт курса | 122 226 ₽ | 4108 ₽/мес. | 9 месяцев | Обзор курса | |
| Профессия Python-разработчик Перейти на сайт курса | 140 040 ₽ | 4279 ₽/мес. | 10 месяцев | Обзор курса |
Больше программ — в полном каталоге курсов по Python




