Python 打包工具对比:PyInstaller 和 Nuitka 使用详解

Page content

  Nuitka和PyInstaller都是优秀的打包工具,各有优缺点。

创建虚拟环境:

搭建python虚拟环境是因为打包工具貌似会把整个python环境的库给打包,所以需要创建虚拟环境。

virtualenv venv --python=python3.12
cd venv/Scripts
activate

pyinstaller打包:

pyinstaller是利用操作系统的特性,将所有依赖项打包到一个文件中,可以在没有python环境的机器上运行。

pip install pypdf2 loguru wxPython pyinstaller

执行检查所需库是否安装完整: python main_app.py

下载upx.exe到项目目录: https://github.com/upx/upx/releases/

打包: pyinstaller -F -w main_app.py

打包后的文件在到dist目录下,执行报错:

Traceback (most recent call last):
  File "main_app.py", line 5, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
  File "pdf_utils.py", line 2, in <module>
ModuleNotFoundError: No module named 'PyPDF2'

运行以下命令检查模块版本 python -c "import PyPDF2; print(PyPDF2.__version__)"

修改打包命令,在打包时明确指定 PyPDF2 pyinstaller -w --onefile --hidden-import=PyPDF2 main_app.py

本项目使用pyinstaller生成文件大小13M。

如果遇到找不到静态资源文件,将资源文件夹放到同打包后的可执行文件相同目录。

nuitka打包:

nuitka的作用是将python程序转换成C语言的可执行elf文件。这样在运行时就可以享受到C语言处理过程中的优化,提高速度。

根据网上有人测试,Nuitka打包后的exe比Pyinstaller打包后的exe运行速度提升30%。

使用nuitka打包是pyinstaller所用时间显著慢于pyinstaller,但是仍然在有限的时间内可以完成。

pip install pypdf2 loguru wxPython nuitka
#卸载
pip uninstall pyinstaller

打包命令:

nuitka --mingw64 --show-progress --standalone --windows-console-mode=disable --onefile --remove-output --output-dir=out main_app.py

第一次过程比较慢,提示需要下载 mingw64:

Nuitka: Completed Python level compilation and optimization.
Nuitka: Generating source code for C backend compiler.
Nuitka-Memory: Total memory usage before generating C code:: 459.47 MB (481787904 bytes)
Nuitka-Memory: Total memory usage before running scons: 462.19 MB (484642816 bytes)
Nuitka: Running data composer tool for optimal constant value handling.
Nuitka: Running C compilation via Scons.
Nuitka will use gcc from MinGW64 of winlibs to compile on Windows.
Is it OK to download and put it in 'C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\Cache\downloads\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2'.

Fully automatic, cached. Proceed and download? [Yes]/No : Yes
Nuitka: Downloading
Nuitka: 'https://github.com/brechtsanders/winlibs_mingw/releases/download/14.2.0posix-19.1.1-12.0.0-msvcrt-r2/winlibs-x86_64-posix-seh-gcc-14.2.0-llvm-19.1.1-mingw-w64msvcrt-12.0.0-r2.zip'.
Nuitka: Extracting to
Nuitka: 'C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\Cache\downloads\gcc\x86_64\14.2.0posix-19.1.1-12.0.0-msvcrt-r2\mingw64\bin\gcc.exe'
Nuitka-Scons: Backend C compiler: gcc (gcc 14.2.0).
Nuitka-Scons: Backend linking program with 82 files (no progress information available for this stage).
Nuitka-Scons: Compiled 81 C files using ccache.
Nuitka-Scons: Cached C files (using ccache) with result 'cache miss': 81
Nuitka-Inclusion: Analyzing dependencies of 'out\main_app.dist\main_app.exe'.
Nuitka will make use of Dependency Walker (https://dependencywalker.com) tool
to analyze the dependencies of Python extension modules.

Is it OK to download and put it in 'C:\Users\Administrator\AppData\Local\Nuitka\Nuitka\Cache\downloads\depends\x86_64'.

打包后不能运行,使用重新生成检查运行结果(测试的时候不要加–onefile,因为会增加打包的时间,在确定了没有问题再添加)

nuitka --mingw64 --show-progress --standalone --output-dir=out main_app.py

提示错误:

Traceback (most recent call last):
  File "D:\PDF_SP~1\out\MAIN_A~1.DIS\main_app.py", line 4, in <module>
  File "D:\PDF_SP~1\out\MAIN_A~1.DIS\PDF_Split_UI.py", line 11, in <module PDF_Split_UI>
  File "D:\PDF_SP~1\out\MAIN_A~1.DIS\wx\xrc.py", line 10, in <module wx.xrc>
ModuleNotFoundError: No module named 'wx._xml'

明确告知 nuitka 包含特定的模块:

nuitka --mingw64 --show-progress --standalone --include-module=wx._xml --enable-plugin=pylint-warnings --output-dir=out main_app.py

可以运行,打包为单独的文件(–onefile)、关闭控制台输出(–windows-console-mode=disable):

nuitka --mingw64 --show-progress --onefile --standalone --windows-console-mode=disable --include-module=wx._xml --enable-plugin=pylint-warnings --output-dir=out main_app.py

本项目使用nuitka生成文件大小13.7M。

如果遇到找不到静态资源文件,将资源文件夹放到同打包后的可执行文件相同目录。

创建一个批处理文件来测量两种方式生成的程序启动时间差:

powershell Measure-Command { Start-Process "main_app.exe" }
pause

pyinstaller生成的约90ms、nuitka生成的约86ms。