Дистрибуция Python: PyInstaller vs Nuitka vs shiv
Три подхода к тому, чтобы отдать юзеру «просто файл, который работает».
PyInstaller
Пакетит CPython + байткод + зависимости в один файл или каталог. Не компилирует.
pip install pyinstaller
pyinstaller --onefile --name app main.py
- + Зрелый, много плагинов, кросс-платформенный
- + Быстрая сборка (~30 сек)
- − Большой размер (встроенный Python ~30 MB)
- − Байткод легко извлечь (
pyinstxtractor) - − Медленный запуск (распаковка + инициализация интерпретатора)
Nuitka
Компилирует в C → нативный бинарник. Подробнее в статье про Nuitka + GHA.
- + Нативная скорость, нет встроенного Python
- + Сложнее реверсить
- − Долгая сборка (минуты, не секунды)
- − Нужен C-компилятор на целевой (для кросс-сборки)
- − Меньше плагинов, чем у PyInstaller
shiv (zipapp)
Пакетит зависимости + код в исполняемый .zip с shebang #!/usr/bin/env python3. Нужен Python на целевой.
pip install shiv
shiv -c app -o app.zip -e main.py .
chmod +x app.zip
./app.zip
- + Минимальный размер (только код + deps)
- + Быстрая сборка (секунды)
- + Легко обновить (заменить zip)
- − Нужен Python 3 на целевой
- − Нет защиты (zip = читаемый)
Когда что
| Сценарий | Выбор |
|---|---|
| CLI для юзеров без Python | Nuitka (onefile) или PyInstaller |
| Внутренний инструмент, Python есть | shiv |
| Нужна защита кода | Nuitka |
| Быстрая итерация, CI | shiv или PyInstaller |
| GUI (Tkinter/Qt) | PyInstaller (лучшая поддержка) |
Гибрид
Частый паттерн: shiv для dev/CI + Nuitka для релизного бинарника. В workflow собираешь оба, shiv — для smoke-тестов, Nuitka — для дистрибуции.