Инструменты для превращения Python кода в исполняемое приложение
Компиляция кода Python в исполняемый EXE файл позволяет распространять приложение без необходимости установки интерпретатора. В этой статье рассматриваются несколько инструментов с подробными примерами и инструкциями.
Способы компиляции Python кода в EXE
Как упаковать Python скрипт в один EXE файл с помощью PyInstaller?
PyInstaller считается самым популярным решением. Он анализирует зависимости, объединяет их и создает автономный исполняемый файл.
Установка:
pip install pyinstallerкомпиляция кода python (компиляция кода python)
Базовая команда для создания однофайлового EXE:
pyinstaller --onefile my_script.pyPython compile py (компиляция python кода)
После выполнения в папке dist появится my_script.exe. Пример скрипта my_script.py:
import sys
def main():
print('Привет, мир!')
print(f'Python {sys.version}')
if __name__ == '__main__':
main()
Python to c to exe (конвертация python в c и в exe)
Команда pyinstaller --onefile my_script.py создает один EXE, который включает интерпретатор и все используемые библиотеки.
Типичная ошибка: при запуске EXE появляется окно и сразу закрывается. Чтобы увидеть ошибку, добавьте --console или запустите из командной строки. Также возможно неверное указание пути к данным, если приложение использует файлы. Для корректного доступа к ресурсам следует использовать sys._MEIPASS.
Решение: в коде обращайтесь к временной папке, создаваемой PyInstaller:
import sys, os
def resource_path(relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath('.'), relative_path)Как использовать cx_Freeze для создания EXE?
cx_Freeze - модульный упаковщик с гибкой настройкой. Установка:
pip install cx-freezeПример файла setup.py:
from cx_Freeze import setup, Executable
setup(
name='MyApp',
version='1.0',
description='Пример',
executables=[Executable('my_script.py')]
)Запуск:
python setup.py buildEXE создается в папке build. Для однофайлового режима cx_Freeze не поддерживает - всегда получается папка с библиотеками. Для уменьшения размера можно исключить неиспользуемые модули.
Проблема: пропущенные модули, особенно с динамическими импортами. Добавьте их в список packages в опциях:
options = {'build_exe': {'packages': ['os', 'sys']}}Как создать EXE с помощью Nuitka в режиме C компиляции?
Nuitka транслирует Python код в C++, что ускоряет выполнение и уменьшает размер. Установка:
pip install nuitkaКоманда для компиляции в один файл (требуется MinGW на Windows):
nuitka --onefile --standalone my_script.pyДля лучшей оптимизации:
nuitka --onefile --standalone --enable-plugin=tk-inter --windows-disable-console my_script.pyРезультат - my_script.exe с минимальным временем запуска.
Частая ошибка - Nuitka не находит компилятор C. Установите Visual Studio Build Tools или MinGW-w64 и добавьте в PATH.
Как упаковать Python приложение в EXE с помощью py2exe (устаревший, но все еще используемый)?
py2exe поддерживает Python 3.5+. Установка:
pip install py2exeСоздайте setup.py:
from distutils.core import setup
import py2exe
setup(
console=['my_script.py']
)Запуск:
python setup.py py2exeВ папке dist появляется EXE и DLL. Для однофайлового варианта требуется дополнительный скрипт, который собирает все в архив.
Проблема: библиотеки могут не копироваться. Используйте опцию includes:
setup(console=['my_script.py'], options={'py2exe': {'includes': ['os']}})Как применить PyOxidizer для создания EXE?
PyOxidizer (oxidizer) создает самодостаточные бинарники с интерпретатором, встроенным через Rust. Установка требует Rust toolchain.
После установки инициализация проекта:
oxidize new my_app
cd my_app
oxi buildВ результате получается EXE около 10 МБ. Настройка происходит в файле pyoxidizer.bzl. Пример:
def make_exe():
dist = default_python_distribution()
policy = dist.make_python_packaging_policy()
python_config = dist.make_python_interpreter_config()
python_config.run_module = 'my_script'
exe = dist.to_python_executable(
name='my_app',
packaging_policy=policy,
config=python_config
)
return exe
Затем запуск oxi build.
Сложность: требуется Rust, ограниченная поддержка динамических модулей. Для больших библиотек (например, TensorFlow) используют PyInstaller.
Расширенные примеры компиляции и настройки
Ниже приведены дополнительные сценарии использования инструментов с детализацией параметров и особенностей.
PyInstaller: скрытый импорт и уменьшение размера
Иногда PyInstaller не видит модули, которые импортируются динамически. Решение - явно указать их через --hidden-import.
pyinstaller --onefile --hidden-import pandas --hidden-import numpy my_script.pyДля уменьшения размера можно выключить UPX (если настроен) или удалить неиспользуемые модули с помощью --exclude-module:
pyinstaller --onefile --exclude-module matplotlib --exclude-module tkinter a.pyСравнение размеров (исходный скрипт 2 КБ):
Без исключения: 35 МБ С исключением: 18 МБ
Spec-файл PyInstaller для сложных проектов
При частой сборке лучше создать .spec. Пример:
pyi-makespec --onefile --noconsole my_script.pyРедактирование spec файла:
a = Analysis(['my_script.py'],
pathex=[],
binaries=[],
datas=[('data.txt', '.')],
hiddenimports=['PIL'],
hookspath=[],
runtime_hooks=[],
excludes=['tkinter'],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data, cipher=None)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='my_script',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False, # скрыть консоль
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None)Запуск сборки:
pyinstaller my_script.speccx_Freeze: включение дополнительных файлов
Если приложение использует изображения или конфиги, их нужно копировать явно:
from cx_Freeze import setup, Executable
import sys
options = {
'build_exe': {
'include_files': [('images/', 'images'), ('config.ini', 'config.ini')],
'packages': ['os', 'sys'],
}
}
setup(
name='MyApp',
version='1.0',
description='',
options=options,
executables=[Executable('my_script.py', base='Win32GUI' if sys.platform == 'win32' else None)]
)Сборка:
python setup.py build_exeРезультат - папка с EXE и всеми файлами.
Nuitka: компиляция с плагинами и отладкой
Для приложений на Tkinter нужно активировать плагин:
nuitka --onefile --standalone --enable-plugin=tk-inter --windows-disable-console --output-dir=myapp my_script.pyЕсли требуется отладить ошибки, используйте --show-modules и --show-scons:
nuitka --onefile --standalone --show-modules --show-scons my_script.pyПример вывода:
Parsing > my_script.py Scanning modules: sys, struct, math Compiling to C...
Для создания мультиплатформенной сборки используйте --windows-icon или --linux-icon.
PyOxidizer: создание минимального EXE
После инициализации проекта можно настроить удаление лишних модулей. В pyoxidizer.bzl добавьте:
def make_exe():
dist = default_python_distribution()
policy = dist.make_python_packaging_policy()
policy.allow_in_memory_shared_library_import = True
python_config = dist.make_python_interpreter_config()
python_config.run_command = 'print("Hello from Oxidizer")'
exe = dist.to_python_executable(
name='small_app',
packaging_policy=policy,
config=python_config,
)
exe.add_python_resources(exe.pip_install(['click==8.1.0'])) # установка библиотек
return exe
Затем oxi build. Размер получается ~3 МБ (минимальный).