Nuitka 是一个强大的 Python 编译器,它将 Python 代码编译成 C 代码,然后使用标准的 C 编译器(如 GCC、Clang 或 MSVC)生成可执行文件。Nuitka 的主要目标是实现完整的 Python 兼容性,同时提供显著的性能提升和更小的文件体积。以下是 Nuitka 的一些关键特点,以及与 PyInstaller 的区别。
性能提升:Nuitka 通过将 Python 代码编译为 C 代码,进而编译为本地机器代码,提升了 Python 程序的运行速度。特别是对于计算密集型任务,Nuitka 能带来显著的性能改进。
完整的 Python 兼容性:Nuitka 完全支持 Python 2 和 Python 3 的所有语言特性,包括复杂的元类和生成器表达式等。它能运行几乎所有的 Python 程序,并且在性能上有所改进。
生成独立的可执行文件:Nuitka 可以生成无需 Python 运行时环境的独立可执行文件(Standalone 模式)。这对于不想让用户安装 Python 环境的应用非常有用。
与 C 编译器集成:Nuitka 将 Python 转换为 C 代码,并使用系统的 C 编译器(如 GCC、MSVC、Clang)来生成高效的可执行文件。因此,Nuitka 生成的文件在性能和兼容性上都有显著优势。
细粒度的优化:Nuitka 对代码进行了一些低级优化,包括删除未使用的代码、函数内联和数据结构优化。这些优化有助于减少代码大小并提升运行效率。
支持多线程:Nuitka 可以更好地利用多核 CPU 来进行编译,提高了编译速度,特别是对于大型项目。
性能:Nuitka 的核心优势在于它将 Python 代码编译为本地 C 代码,从而提高了性能。而 PyInstaller 只是将 Python 代码打包成一个包含解释器和依赖项的可执行文件,并不会带来运行时的性能提升。
文件大小:Nuitka 编译的可执行文件通常比 PyInstaller 打包的文件要小,尤其是在启用 UPX 压缩的情况下。PyInstaller 打包的文件往往较大,因为它包含了完整的 Python 运行时环境。
兼容性:Nuitka 提供了对 Python 语言的完整支持,确保所有语言特性都可以正常运行。而 PyInstaller 则主要依赖于现有的 Python 解释器,可能会遇到某些复杂代码无法正确打包的情况。
依赖处理:PyInstaller 的依赖项检测机制比较强大,适合处理复杂的依赖树,但它生成的可执行文件包含了整个 Python 解释器。Nuitka 则通过生成更为精简的独立文件来管理依赖。
编译时间:由于 Nuitka 涉及到 C 编译器的使用,编译时间通常比 PyInstaller 更长,尤其是对于大型项目。这是性能提升带来的一个代价。
跨平台支持:PyInstaller 支持更广泛的操作系统平台(如 Windows、macOS 和 Linux),而 Nuitka 在跨平台上也有良好支持,但通常需要在目标平台上进行编译以确保兼容性。
Nuitka 是一个真正的编译器,它可以将 Python 代码编译为本地机器码,带来性能提升和较小的可执行文件体积。它适合那些需要优化性能的应用程序。而 PyInstaller 则更适合快速打包和部署 Python 应用程序,但不会带来性能上的改进。
通过选择 Nuitka 或 PyInstaller,开发者可以根据应用场景的需要,在性能优化和打包速度之间进行权衡。
Nuitka 提供了丰富的选项和参数,允许开发者控制编译过程的各个方面。以下是 Nuitka 的一些常用基本选项介绍,涵盖了从编译模式、优化到输出控制等多个方面。
--standalone
:生成一个独立的可执行文件,包含所有需要的依赖项。生成的文件可以在没有 Python 运行环境的机器上运行。
nuitka --standalone main.py
--onefile
:将所有内容(包括依赖项和 Python 解释器)打包到一个单独的可执行文件中,适合分发和部署。
nuitka --onefile main.py
--module
:将 Python 源代码编译为一个可重用的动态库,而不是一个独立的可执行文件。适用于将 Python 模块打包成扩展模块。
nuitka --module mymodule.py
--run
:编译并立即运行 Python 脚本。适用于测试代码的执行效果。
nuitka --run main.py
--lto
:启用链接时优化(Link Time Optimization)。该选项可以进一步优化编译结果,使可执行文件的性能提升。
nuitka --lto main.py
--plugin-enable=upx
:启用 UPX 压缩,压缩生成的可执行文件以减小文件体积。
nuitka --plugin-enable=upx main.py
--nofollow-import-to=<module>
:防止 Nuitka 跟踪特定模块的导入。可以用来优化编译时间并排除不必要的模块。
nuitka --nofollow-import-to=tkinter main.py
--remove-output
:删除之前生成的输出文件,确保编译时不会使用旧的缓存或输出。
nuitka --remove-output main.py
--windows-disable-console
或 --windows-console-mode=disable
:禁用控制台窗口(用于 GUI 程序),使程序运行时不显示命令行窗口。
nuitka --windows-disable-console main.py
--windows-icon-from-ico=<path>
:指定图标文件路径,为生成的可执行文件添加自定义图标。
nuitka --windows-icon-from-ico="icon.ico" main.py
--output-dir=<dir>
:指定输出目录,编译生成的文件将被放置在该目录中。方便将编译结果分类存放。
nuitka --output-dir=out main.py
--show-progress
:在编译过程中显示详细的进度信息。这对于调试和了解编译过程非常有帮助。
nuitka --show-progress main.py
--no-pyi-file
:不生成 .pyi
类型的文件。该文件通常用于类型提示和模块导入时的代码补全。
nuitka --no-pyi-file main.py
--jobs=<N>
:设置并行编译的线程数,以利用多核 CPU 提升编译速度。建议根据 CPU 核心数量调整。
nuitka --jobs=4 main.py
--mingw64
:强制使用 MinGW-w64 编译器进行编译,适用于 Windows 平台,特别是对于没有 MSVC 编译器的环境。
nuitka --mingw64 main.py
--msvc
:使用 MSVC(Microsoft Visual C++)编译器进行编译,适用于 Windows 平台。
nuitka --msvc main.py
--clang
:强制使用 Clang 编译器进行编译。适用于支持 Clang 的平台(如 macOS 和 Linux)。
nuitka --clang main.py
--enable-plugin=<plugin>
:启用指定的插件。例如,tk-inter
插件可用于打包 tkinter 应用程序。
nuitka --enable-plugin=tk-inter main.py
--plugin-enable=<plugin>
:启用已安装的插件。用于启用如 upx
等插件进行功能扩展。
nuitka --plugin-enable=upx main.py
--debug
:启用调试信息输出。这可以帮助跟踪代码执行中的错误或问题。
nuitka --debug main.py
--trace-execution
:启用执行跟踪日志,可以跟踪代码执行过程中的详细信息,用于调试复杂问题。
nuitka --trace-execution main.py
--recompile-c-only
:只重新编译 C 代码而不重新编译 Python 部分,用于加快开发过程中的调试周期。
nuitka --recompile-c-only main.py
Nuitka 提供了多种选项来控制 Python 代码的编译过程,涵盖了从优化、压缩、输出控制到并行编译和插件支持的多个方面。通过灵活使用这些参数,开发者可以根据项目需求最大限度地优化生成的可执行文件,无论是提升性能还是减少文件体积。
在这一部分,我们将详细介绍以下 Nuitka 打包指令的每一个参数和作用,帮助你理解打包过程中发生了什么,以及如何调整它们来适应你的需求。
python -m nuitka --mingw64 --standalone --output-dir=out --show-progress --onefile --plugin-enable=upx --upx-binary="./upx-4.2.4-win64/upx.exe" --jobs=4 --include-module=wx --include-module=wx.xrc --include-module=wx._xml --windows-console-mode=disable --windows-icon-from-ico="dpad.ico" main.py
python -m nuitka
-m
选项来运行 Nuitka 模块。通过 python -m nuitka
,你可以确保使用的是当前 Python 环境下安装的 Nuitka,不需要关心系统路径中的命令冲突问题。--mingw64
--standalone
--output-dir=out
out
目录中。这使得输出文件可以与源文件分离,便于管理。--show-progress
--onefile
--plugin-enable=upx
--upx-binary=
--jobs=4
--include-module=wx --include-module=wx.xrc --include-module=wx._xml
wxPython
库及其相关模块(wx.xrc
和 wx._xml
)包含在打包过程中。尽管 Nuitka 会自动检测依赖关系并包含模块,但有时动态导入的模块可能无法被自动检测到,因此需要手动显式指定。--windows-console-mode=disable
--windows-icon-from-ico="dpad.ico"
.ico
文件为你的程序自定义图标,这对于品牌化和提高程序的视觉吸引力很有帮助。main.py
这个打包命令综合了多个 Nuitka 的高级选项,从使用 MinGW 编译器到启用 UPX 压缩,再到生成一个无控制台的独立可执行文件。这些选项确保了打包后的文件不仅体积小、性能高,而且在没有 Python 环境的机器上也能正常运行,同时配有自定义图标,非常适合生产环境的应用分发。
使用 --mingw64
选项与不使用它的打包过程的主要区别在于编译器的选择和一些具体的特性。以下是详细的区别:
使用 --mingw64
:
不使用 --mingw64
:
MSVC 编译器(默认编译器,不使用 --mingw64
时可能被选用):
MinGW-w64 编译器(使用 --mingw64
时):
使用 --mingw64
:
不使用 --mingw64
:
使用 --mingw64
:
不使用 --mingw64
:
使用 --mingw64
:推荐用于没有安装 Visual Studio 的环境或者希望使用开源工具链的开发者。这是一个轻量级、跨平台的编译器,适合大多数 Windows 项目。
不使用 --mingw64
:如果你的系统上已经配置了 MSVC 编译器,并且希望利用微软官方工具链的优化,那么可以不使用 --mingw64
,这样 Nuitka 会自动选择 MSVC 进行编译,通常性能和稳定性会更高。
在实际项目中,选择哪种编译器主要取决于你的开发环境和项目需求。如果没有特殊需求,不使用 --mingw64
并让 Nuitka 自动选择系统编译器通常是更方便的选择。
python -m nuitka --standalone --output-dir=out1 --onefile --jobs=4 --include-module=wx --include-module=wx.xrc --include-module=wx._xml --windows-console-mode=disable --windows-icon-from-ico="dpad.ico" main.py