Как сделать exe из Python-скрипта (PyInstaller)
Как создать exe из Python-скрипта через PyInstaller: --onefile, --windowed, иконка, файлы и sys._MEIPASS, spec-файл, антивирусы и альтернативы.
Содержание · 13 разделов
- Быстрый ответ
- Как PyInstaller превращает скрипт в exe
- Подготовьте виртуальное окружение
- Первая сборка: pyinstaller —onefile
- Один файл или одна папка
- Программа с окном: —windowed и —icon
- Файлы данных в exe: —add-data и sys._MEIPASS
- Почему файл не находится и что такое sys._MEIPASS
- Файлы, которые программа меняет
- Spec-файл: сборка без длинной команды
- Скрытые импорты: ModuleNotFoundError в exe
- Альтернативы PyInstaller: что выбрать
- Ограничения exe из Python
- Exe собирается только под свою ОС
- Антивирусы и SmartScreen
- Размер
- Совместимость с Python 3.15
- Исходный код можно извлечь
- Частые ошибки
- Консольное окно мелькает и сразу закрывается
- FileNotFoundError с путём _MEIxxxxxx
- «pyinstaller» не является внутренней или внешней командой
- В exe нет библиотеки, хотя она установлена
- UnicodeEncodeError при выводе в файл
- Программа бесконечно запускает свои копии
- Частые вопросы
- Нужен ли Python на компьютере, где запускают exe?
- Можно ли собрать exe для Windows на Linux или macOS?
- Почему exe из одного файла долго запускается?
- Как сделать установщик вместо exe?
- Можно ли продавать программу, собранную PyInstaller?
- Как добавить в exe версию и название компании?
- Итог
Чтобы сделать exe из Python-скрипта, установите PyInstaller (pip install pyinstaller) и выполните в папке со скриптом pyinstaller --onefile script.py. Готовый script.exe появится в папке dist. Внутри него упакованы интерпретатор Python и все библиотеки, поэтому на компьютере пользователя Python не нужен. Собирать exe нужно в Windows: PyInstaller делает программу только для той системы, на которой запущен.
Ниже — сборка в виртуальном окружении, программа с окном и иконкой, файлы данных и sys._MEIPASS, spec-файл, скрытые импорты, выбор между PyInstaller, auto-py-to-exe, Nuitka, cx_Freeze и Briefcase, а также ограничения: антивирусы, размер и поддержка Python 3.15. Все команды проверены на Windows 11 с PyInstaller 6.22.3 и Python 3.12, сборка дополнительно проверена на релиз-кандидате Python 3.15.0rc1.
Быстрый ответ
| Задача | Команда или опция |
|---|---|
| Установить PyInstaller | pip install pyinstaller |
| Собрать один exe-файл | pyinstaller --onefile script.py |
| Собрать папку с exe (запускается быстрее) | pyinstaller script.py |
| Убрать консольное окно у программы с GUI | --windowed (синоним --noconsole) |
| Задать значок exe | --icon=app.ico |
| Положить в exe файлы и папки | --add-data "data:data" |
| Подключить модуль, который не нашёлся | --hidden-import имя.модуля |
| Задать имя exe | --name MyApp |
| Пересобрать по сохранённым настройкам | pyinstaller app.spec |
| Где искать результат | папка dist, рядом — build и файл script.spec |
Как PyInstaller превращает скрипт в exe
PyInstaller не переводит Python в машинный код. Он анализирует импорты скрипта, собирает нужные модули в виде байт-кода (.pyc), добавляет библиотеку интерпретатора (python312.dll), DLL расширений и небольшой загрузчик (bootloader). Загрузчик запускает встроенный Python и выполняет ваш код.
Результат бывает двух видов:
- Одна папка (onedir, режим по умолчанию) — в
dist\scriptлежатscript.exeи папка_internalс библиотеками. Программу передают целиком, всей папкой. - Один файл (onefile, флаг
--onefile) — всё сжато в один exe. При каждом запуске он распаковывает содержимое во временную папку вида%TEMP%\_MEIxxxxxx, а после завершения удаляет её.
Из устройства onefile следуют почти все особенности: медленный первый запуск, поиск файлов данных через sys._MEIPASS и подозрения антивирусов.
Подготовьте виртуальное окружение
Собирайте exe в отдельном виртуальном окружении, где установлены только нужные проекту пакеты. Если собирать в общем Python, PyInstaller может затянуть в exe лишние библиотеки, на которые ссылаются ваши зависимости, и размер вырастет в разы. Кроме того, в чистом окружении сразу видно, каких пакетов не хватает.
Windows (PowerShell):
cd C:\projects\hello
py -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install pyinstaller
pyinstaller --version
# → 6.22.3
В cmd окружение активируется командой .venv\Scripts\activate.bat.
macOS и Linux:
cd ~/projects/hello
python3 -m venv .venv
source .venv/bin/activate
python -m pip install pyinstaller
pyinstaller --version
Затем установите в это же окружение зависимости проекта: по одной через pip или списком из requirements.txt. Если Python ещё не установлен, начните с руководства «Как установить Python».
Совет: перед сборкой запустите скрипт из активированного окружения обычной командой
python script.py. Если он падает сModuleNotFoundError, exe тоже не заработает — сначала установите недостающие библиотеки.
Первая сборка: pyinstaller —onefile
Возьмём простой консольный скрипт hello.py:
import platform
import sys
print(f"Привет! Python {platform.python_version()}")
print("Запущен из exe:", getattr(sys, "frozen", False))
input("Нажмите Enter, чтобы закрыть окно...")
Атрибут sys.frozen появляется только в собранной программе, по нему код узнаёт, что запущен из exe. Последняя строка с input() нужна, чтобы консольное окно не закрылось сразу после вывода, если запустить exe двойным щелчком.
Соберите один файл:
pyinstaller --onefile hello.py
Сборка заняла около 17 секунд. В конце лога PyInstaller пишет, где лежит результат:
334 INFO: PyInstaller: 6.22.3, contrib hooks: 2026.8
334 INFO: Python: 3.12.10
371 INFO: Platform: Windows-11-10.0.26200-SP0
...
16965 INFO: Building EXE from EXE-00.toc completed successfully.
16981 INFO: Build complete! The results are available in: C:\projects\hello\dist
В папке проекта появились:
dist\hello.exe— готовая программа, её и отдают пользователю;build\— промежуточные файлы и отчёт о пропущенных модуляхwarn-hello.txt; папку можно удалить;hello.spec— настройки сборки, к нему вернёмся ниже.
Запуск:
> .\dist\hello.exe
Привет! Python 3.12.10
Запущен из exe: True
Нажмите Enter, чтобы закрыть окно...
Файл hello.exe весит около 7 МБ, хотя в скрипте шесть строк: это цена встроенного интерпретатора.
Один файл или одна папка
Если exe будут запускать часто, сравните режимы. Время старта мы замерили на Windows 11 для скрипта, который печатает одну строку и завершается.
| Критерий | --onefile (один файл) | По умолчанию (одна папка) |
|---|---|---|
| Что получает пользователь | один app.exe | папку с app.exe и _internal |
| Запуск (наш замер) | 1,4–2,6 с при каждом запуске | 0,1–0,3 с при повторных запусках |
| Размер | меньше: содержимое сжато | больше: наш пример с tkinter занял 26 МБ |
| Ложные срабатывания антивирусов | чаще: распаковка во временную папку | реже |
| Файлы, которые меняет программа | теряются после выхода (временная папка) | сохраняются |
| Удобно для | небольших утилит, отправки одним файлом | больших программ и установщиков |
Для начала собирайте без --onefile: проще найти, какого файла не хватает. Когда программа заработает, переключитесь на один файл, если он нужен.
Программа с окном: —windowed и —icon
У программы с графическим интерфейсом консольное окно не нужно. Пример на tkinter app.py показывает приветствие из текстового файла и ставит значок окна:
import sys
import tkinter as tk
from pathlib import Path
def resource_path(relative: str) -> Path:
"""Путь к файлу рядом со скриптом или внутри exe."""
base = Path(getattr(sys, "_MEIPASS", Path(__file__).resolve().parent))
return base / relative
greeting = resource_path("data/greeting.txt").read_text(encoding="utf-8")
root = tk.Tk()
root.title("Приветствие")
root.iconbitmap(resource_path("app.ico"))
tk.Label(root, text=greeting, font=("Segoe UI", 12), padx=30, pady=20).pack()
tk.Button(root, text="Закрыть", command=root.destroy).pack(pady=(0, 15))
root.mainloop()
Структура проекта:
hello/
├── app.py
├── app.ico
└── data/
└── greeting.txt
Команда сборки (в PowerShell и bash одинаковая):
pyinstaller --onefile --windowed --icon=app.ico --add-data "data:data" --add-data "app.ico:." app.py
Что делает каждая опция:
--windowed(или--noconsole) — exe запускается без чёрного окна консоли. Действует в Windows и macOS; в macOS при этом собирается пакет.app. В Windows режим без консоли включается сам, если главный скрипт называется*.pyw.--icon=app.ico— значок самого exe в Проводнике и на панели задач. В Windows нужен формат.ico; картинку PNG PyInstaller конвертирует сам, если в окружении установлен Pillow. В.icoлучше положить несколько размеров, от 16×16 до 256×256 пикселей.--add-data— копирует в сборку папкуdataи файлapp.ico. Об этом — в следующем разделе.
Значок exe и значок окна — разные вещи. --icon меняет только значок файла. Чтобы значок появился в заголовке окна tkinter, файл .ico нужно добавить в сборку через --add-data и загрузить в коде через resource_path(). Без этого iconbitmap() в exe не найдёт файл.
Важно: в режиме
--windowedу программы нет консоли, поэтомуsys.stdoutиsys.stderrравныNone. Вызовprint()ничего не выводит и не падает, а код, который пишет вsys.stdout.write()напрямую (так делают некоторые библиотеки), завершится ошибкойAttributeError. Сообщения программы записывайте в файл через модульlogging.
Если после пересборки Проводник показывает старый значок, это кэш значков Windows: переименуйте exe или скопируйте его в другую папку, и значок обновится.
Файлы данных в exe: —add-data и sys._MEIPASS
PyInstaller находит модули по импортам, но не знает о картинках, шаблонах, JSON и других файлах, которые код открывает по пути. Их добавляют вручную опцией --add-data "ИСТОЧНИК:ПАПКА_В_СБОРКЕ":
--add-data "data:data"— папкаdataцеликом попадёт в папкуdataвнутри сборки;--add-data "app.ico:."— файл попадёт в корень сборки (точка означает корень);- опцию можно повторять сколько угодно раз.
В PyInstaller 6 разделитель источника и назначения — двоеточие на всех системах. В старых инструкциях для Windows встречается точка с запятой ("data;data"): такой вариант Windows-версия тоже принимает, но для кроссплатформенных скриптов сборки используйте двоеточие.
Почему файл не находится и что такое sys._MEIPASS
Если собрать app.py без --add-data, exe упадёт при запуске. В консольной сборке видно, где именно он ищет файл:
Traceback (most recent call last):
File "app.py", line 12, in <module>
greeting = resource_path("data/greeting.txt").read_text(encoding="utf-8")
...
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\user\\AppData\\Local\\Temp\\_MEI123456\\data\\greeting.txt'
[PYI-23976:ERROR] Failed to execute script 'app' due to unhandled exception!
Exe с --windowed вместо текста в консоли покажет окно «Unhandled exception in script» с тем же traceback.
Путь начинается с _MEI123456 во временной папке. Загрузчик PyInstaller записывает в sys._MEIPASS папку, где лежат файлы сборки:
- в режиме одного файла — временная папка
_MEIxxxxxx, куда распаковался exe; - в режиме папки — папка
_internalрядом с exe.
Поэтому пути к файлам нельзя считать от текущей рабочей папки (open("data/greeting.txt")): при двойном щелчке, запуске из другой папки или через ярлык она будет другой. Функция resource_path() из примера берёт sys._MEIPASS в собранной программе и папку скрипта при обычном запуске — один и тот же код работает в обоих случаях.
Начиная с PyInstaller 4.3 то же самое даёт Path(__file__).resolve().parent в главном скрипте: загрузчик подставляет в __file__ путь внутри сборки. sys._MEIPASS удобен, если файлы нужно найти из модуля во вложенной папке проекта.
Файлы, которые программа меняет
Всё, что добавлено через --add-data, в режиме одного файла распаковывается заново при каждом запуске и удаляется после выхода. Настройки, базы SQLite и логи, которые программа записывает, храните вне сборки:
import os
import sys
from pathlib import Path
if getattr(sys, "frozen", False):
app_dir = Path(sys.executable).parent # папка, где лежит exe
else:
app_dir = Path(__file__).resolve().parent
settings_file = app_dir / "settings.json"
# Или в профиле пользователя — туда запись разрешена всегда:
user_dir = Path(os.environ.get("APPDATA", Path.home())) / "MyApp"
user_dir.mkdir(parents=True, exist_ok=True)
sys.executable в собранной программе указывает на сам exe. Папку рядом с exe выбирайте для портативных программ. Если программу установят в C:\Program Files, обычный пользователь не сможет туда писать, поэтому для установленных программ подходит %APPDATA%.
Spec-файл: сборка без длинной команды
При первом запуске PyInstaller создаёт файл app.spec. Это обычный Python-код, в котором записаны все опции сборки. Для команды из примера выше он выглядит так (сокращённо):
a = Analysis(
['app.py'],
pathex=[],
binaries=[],
datas=[('data', 'data'), ('app.ico', '.')],
hiddenimports=[],
excludes=[],
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='app',
upx=True,
console=False,
icon=['app.ico'],
)
Опции командной строки соответствуют параметрам: --add-data → datas, --hidden-import → hiddenimports, --windowed → console=False, --icon → icon, --name → name. Отредактируйте файл, например замените name='app' на name='Greeter', и соберите по нему:
pyinstaller --noconfirm --clean app.spec
# → в dist появится Greeter.exe
--noconfirm перезаписывает прошлую сборку без вопроса, --clean очищает кэш PyInstaller перед сборкой.
Важно: команда
pyinstaller app.py ...с именем скрипта каждый раз генерирует spec-файл заново и затирает ваши правки. После того как вы начали править spec, запускайте сборку только командойpyinstaller app.spec. Создать spec без сборки можно командойpyi-makespecс теми же опциями.
Spec-файл стоит хранить в git вместе с кодом: по нему любой участник проекта или CI-сервер соберёт такой же exe.
Скрытые импорты: ModuleNotFoundError в exe
PyInstaller ищет зависимости по операторам import. Модули, которые загружаются динамически — через importlib.import_module(), __import__() или по имени из настроек, — он не видит. Пример main.py с плагином из папки plugins:
import importlib
name = "report"
plugin = importlib.import_module(f"plugins.{name}")
print(plugin.run())
# → Отчёт готов
Из исходников скрипт работает, а собранный exe падает:
ModuleNotFoundError: No module named 'plugins'
[PYI-29932:ERROR] Failed to execute script 'main' due to unhandled exception!
Укажите такой модуль явно:
pyinstaller --onefile --hidden-import plugins.report main.py
После этого exe выводит «Отчёт готов». Другие инструменты для той же проблемы:
--collect-submodules пакет— добавляет все подмодули установленного пакета, если библиотека грузит плагины по имени;--collect-data пакети--collect-all пакет— добавляют файлы данных пакета или сразу всё: подмодули, данные и DLL;build\main\warn-main.txt— список модулей, которые PyInstaller не нашёл при анализе (большинство записей там безобидны: это модули других ОС);--debug=imports— exe при запуске печатает каждый импорт, так видно, на каком модуле он остановился.
Для популярных библиотек (NumPy, pandas, PyQt, requests и многих других) скрытые импорты уже описаны в хуках пакета pyinstaller-hooks-contrib, который ставится вместе с PyInstaller. Если библиотека всё равно не находится, обновите оба пакета: python -m pip install -U pyinstaller pyinstaller-hooks-contrib. Как разбирать саму ошибку импорта, рассказано в статье про ModuleNotFoundError.
Альтернативы PyInstaller: что выбрать
PyInstaller — самый распространённый вариант с подробной документацией и готовыми хуками для библиотек. Другие инструменты нужны, когда важны графический интерфейс вместо команд, скорость кода, установщик или мобильные платформы.
| Инструмент | Как работает | Один exe-файл | Python 3.15 (версия на PyPI) | Когда выбрать |
|---|---|---|---|---|
| PyInstaller | упаковывает интерпретатор и байт-код | да, --onefile | да, начиная с 6.21 (сейчас 6.22.3) | основной выбор для скриптов и программ с GUI |
| auto-py-to-exe | графический интерфейс к PyInstaller в окне браузера | да, переключатель One File | ставится, внутри — тот же PyInstaller | не хочется запоминать опции командной строки |
| Nuitka | переводит Python в C и компилирует | да, --mode=onefile | экспериментально (4.2.2) | нужна скорость кода или сложнее извлечь исходники |
| cx_Freeze | замораживает скрипт в папку с exe по setup.py или pyproject.toml | нет в Windows, вместо этого установщик MSI | да (8.7.1) | нужен установщик MSI из коробки |
| Briefcase | собирает приложение и установщик для каждой платформы (BeeWare) | нет, установщик MSI в Windows | да (0.4.5) | приложение под Windows, macOS, Linux, iOS и Android из одного проекта |
auto-py-to-exe ставится командой pip install auto-py-to-exe и запускается командой auto-py-to-exe. В окне выбирают скрипт, режим One File или One Directory, консоль или окно, значок и дополнительные файлы, а внизу видна итоговая команда PyInstaller. Её можно скопировать и дальше собирать без интерфейса. Ограничения у него те же, что у PyInstaller.
Nuitka компилирует код через C, поэтому ему нужен компилятор: в Windows — Visual Studio 2022 Build Tools или Zig (MinGW64 с Python 3.13 и новее не работает). Сборка идёт в разы дольше, чем у PyInstaller, а при первом запуске Nuitka предлагает скачать вспомогательные утилиты. Команда для одного файла: python -m nuitka --mode=onefile app.py. Nuitka 4.2.2 официально поддерживает Python до 3.14 и при запуске на 3.15 предупреждает, что поддержка экспериментальная.
cx_Freeze собирает папку с программой, а для распространения в Windows делает установщик командой bdist_msi. Briefcase требует оформить проект по своим правилам (pyproject.toml с настройками BeeWare) и подходит, когда программа изначально пишется как кроссплатформенное приложение.
Ещё один старый инструмент, py2exe, работает только в Windows и в версии 0.14.2 поддерживает Python 3.10–3.14.
Ограничения exe из Python
Exe собирается только под свою ОС
PyInstaller, cx_Freeze и Nuitka не умеют кросс-компиляцию: exe для Windows собирают в Windows, программу для macOS — в macOS, для Linux — в Linux. Команды PyInstaller одинаковые на всех системах, но результат в Linux — исполняемый файл без расширения, в macOS — программа или пакет .app. Если нужны сборки под несколько ОС, используйте виртуальные машины или CI с отдельной задачей для каждой системы, например GitHub Actions.
Учитывайте ещё два ограничения:
- Разрядность. Exe, собранный 64-битным Python, не запустится в 32-битной Windows. Для неё нужен 32-битный Python и отдельная сборка.
- Версия Windows. В exe попадает тот Python, которым вы собирали, вместе с его требованиями к системе. Python 3.13 и новее работает в Windows 10 и 11, для Windows 8.1 подходит Python 3.12, для Windows 7 — Python 3.8. Чтобы программа запускалась на старых системах, собирайте её соответствующей версией Python.
Для Linux PyInstaller не упаковывает системную библиотеку glibc. Программа, собранная на свежем дистрибутиве, может не запуститься на старом, поэтому собирайте на самой старой системе, которую нужно поддерживать.
Антивирусы и SmartScreen
Windows Defender и другие антивирусы иногда помечают exe из PyInstaller как вирус, даже если в коде нет ничего опасного. Причины две. Однофайловый exe при запуске распаковывает себя во временную папку — так же ведут себя упаковщики вредоносных программ. А стандартный загрузчик PyInstaller одинаков у всех пользователей, в том числе у авторов вирусов, и его сигнатура попадает в базы.
Что помогает снизить число ложных срабатываний:
- Соберите программу в режиме папки, без
--onefile. - Обновите PyInstaller до последней версии: в новых релизах загрузчик пересобран.
- Соберите загрузчик PyInstaller из исходников: у собственного загрузчика другая сигнатура, и PyInstaller рекомендует этот способ против ложных срабатываний. Понадобится компилятор C, в Windows — Visual Studio Build Tools.
- Отправьте файл на проверку производителю антивируса как ложное срабатывание. У Microsoft для этого есть страница отправки файлов Microsoft Security Intelligence.
- Подпишите exe сертификатом подписи кода (code signing). Это платная услуга, но подпись снимает и предупреждение SmartScreen «Система Windows защитила ваш компьютер», которое появляется у неподписанных программ, скачанных из интернета.
Пользователю программы без подписи можно объяснить, что в окне SmartScreen нужно нажать «Подробнее» → «Выполнить в любом случае». Гарантированного способа убрать предупреждения во всех антивирусах нет.
Размер
Минимальный консольный exe весит около 7 МБ, программа с tkinter в одном файле — около 10 МБ, в режиме папки — 26 МБ. С pandas, NumPy или PyQt сборка легко занимает сотни мегабайт. Как уменьшить:
- собирайте в виртуальном окружении только с нужными пакетами;
- исключайте ненужные модули:
--exclude-module matplotlib(или списокexcludesв spec-файле), затем проверьте, что программа работает; - импортируйте только те части библиотек, которые нужны программе.
Если в PATH есть утилита UPX, PyInstaller в Windows автоматически сжимает ею DLL. Она экономит место, но иногда повреждает библиотеки (например, некоторые DLL Qt); при странных ошибках запуска пересоберите с --noupx.
Совместимость с Python 3.15
Python 3.15.0 вышел 9 октября 2026 года. PyInstaller поддерживает его с версии 6.21.0: в метаданных PyInstaller 6.22.3 на PyPI указано requires-python >=3.8,<3.16. Мы собрали оба примера статьи (консольный и tkinter) на релиз-кандидате Python 3.15.0rc1 с PyInstaller 6.22.3 — exe запустились без изменений в командах.
Чтобы сборка на новой версии Python прошла:
- обновите PyInstaller и
pyinstaller-hooks-contribдо последних версий: старые релизы PyInstaller не устанавливаются на Python, который не поддерживают; - проверьте, что у всех зависимостей есть колёса (готовые сборки) для 3.15 — иначе
pip installпопытается компилировать пакет из исходников; - для Nuitka пока используйте Python 3.14: на 3.15 версия 4.2.2 работает в экспериментальном режиме.
Исходный код можно извлечь
Exe содержит байт-код .pyc без исходных файлов, но байт-код декомпилируется, и логику программы можно восстановить. Шифрование байт-кода (опция --key) удалено ещё в PyInstaller 6.0. Если нужно усложнить анализ, компилируйте важные модули через Cython или собирайте программу через Nuitka. Пароли, токены и ключи API в коде exe не прячьте: их достанут из любой сборки.
Частые ошибки
Консольное окно мелькает и сразу закрывается
Программа падает при запуске, и окно закрывается вместе с текстом ошибки. Откройте терминал в папке с exe и запустите его оттуда (.\dist\app.exe), чтобы увидеть traceback. Для программы с окном временно соберите вариант без --windowed.
FileNotFoundError с путём _MEIxxxxxx
Файл данных не попал в сборку или код ищет его относительно текущей папки. Добавьте файл через --add-data и стройте путь от sys._MEIPASS или от Path(__file__).parent, как в функции resource_path() выше.
«pyinstaller» не является внутренней или внешней командой
Папка Scripts окружения не в PATH: окружение не активировано или PyInstaller установлен в другой Python. Активируйте окружение или запустите PyInstaller как модуль: python -m PyInstaller --onefile app.py (имя модуля пишется с большими буквами P и I). В macOS и Linux — python3 -m PyInstaller.
В exe нет библиотеки, хотя она установлена
Если ModuleNotFoundError называет установленный пакет, который код импортирует обычным import, скорее всего, PyInstaller запущен из другого Python, где этого пакета нет. Проверьте командой python -m pip show имя_пакета в том окружении, где запускаете сборку, и собирайте через python -m PyInstaller.
UnicodeEncodeError при выводе в файл
Если вывод exe перенаправлен в файл или другую программу (app.exe > log.txt), Python кодирует текст в кодировке ANSI системы. В русской Windows это cp1251: кириллица пройдёт, а эмодзи и символы других алфавитов вызовут UnicodeEncodeError. Переменные окружения PYTHONUTF8 и PYTHONIOENCODING собранный exe не читает. Включите режим UTF-8 при сборке:
pyinstaller --onefile --python-option "X utf8" hello.py
Программа бесконечно запускает свои копии
Так ведёт себя exe, который использует multiprocessing (в том числе через сторонние библиотеки): каждый дочерний процесс снова запускает главный код. Вызовите multiprocessing.freeze_support() первой строкой в блоке if __name__ == "__main__": — для PyInstaller это нужно на всех ОС, включая macOS и Linux.
Частые вопросы
Нужен ли Python на компьютере, где запускают exe?
Нет. Интерпретатор и библиотеки уже внутри exe или папки _internal. Нужны только подходящая ОС и разрядность. Библиотеки времени выполнения Visual C++, которые требуются Python в Windows, PyInstaller тоже кладёт в сборку.
Можно ли собрать exe для Windows на Linux или macOS?
Штатно — нет, PyInstaller собирает программу только для той системы, где запущен. Рабочие варианты — виртуальная машина с Windows или CI с Windows-сборщиком. Сборка через Wine иногда работает, но официально не поддерживается.
Почему exe из одного файла долго запускается?
При каждом запуске он распаковывает интерпретатор и библиотеки во временную папку, а антивирус проверяет эти файлы. В нашем замере простой скрипт стартовал за 1,4–2,6 секунды в режиме одного файла и за доли секунды в режиме папки. Если скорость запуска важна, распространяйте папку.
Как сделать установщик вместо exe?
Соберите программу в режиме папки и упакуйте её бесплатным конструктором установщиков, например Inno Setup или NSIS: он создаст setup.exe с ярлыками в меню «Пуск» и удалением через «Приложения». Альтернативы — bdist_msi в cx_Freeze и Briefcase, которые сами делают установщик MSI.
Можно ли продавать программу, собранную PyInstaller?
Да. PyInstaller распространяется по лицензии GPL 2.0 с исключением: exe, собранные из вашего кода, можно распространять под любой лицензией, в том числе коммерческой, и не нужно упоминать PyInstaller. Проверьте только лицензии библиотек, которые попали в сборку: например, PyQt распространяется под GPL или по коммерческой лицензии.
Как добавить в exe версию и название компании?
В Windows эти сведения видны в свойствах файла на вкладке «Подробно». Их задаёт опция --version-file version.txt: шаблон файла можно получить из любого существующего exe командой pyi-grab_version путь\к\программе.exe, затем отредактировать поля и пересобрать.
Итог
Основной путь — PyInstaller в виртуальном окружении: pyinstaller --onefile --windowed --icon=app.ico --add-data "data:data" app.py. Файлы данных ищите через sys._MEIPASS или Path(__file__).parent, изменяемые данные храните рядом с exe или в %APPDATA%, а повторные сборки запускайте по spec-файлу. Если важны скорость запуска и меньше претензий от антивирусов, распространяйте сборку папкой или установщиком. Помните, что exe работает только в той ОС, где его собрали. Другие материалы о настройке рабочего места — в разделе «Установка Python и настройка окружения».
- #Python
- #PyInstaller
- #exe
- #Windows
- #Nuitka