说实话,打包Python代码这事儿,估计每个Pythoner都头疼过。PyInstaller、cx_Freeze啥的都用过吧?动不动就几百兆的包,还经常缺这缺那,运行时报个“module not found”能让人抓狂一整天。
后来我翻到了一个叫Nuitka的开源项目,你猜怎么着?它压根不是打包工具,是个正经的 Python 编译器——把你的Python代码直接编译成C,再生成可执行文件。效果嘛,就跟用C写出来的一样,速度蹭蹭涨,而且依赖问题少了一大半。
啥是Nuitka?
简单说,Nuitka会把你的Python脚本翻译成C代码,然后调用本地的 C/C++ 编译器(比如gcc、MSVC)生成真正的机器码。它跟CPython完全兼容,支持Python 2.6到3.13——对,连最新的3.13都行。
跟那些纯打包工具不一样,Nuitka编译出来的程序直接调用libpython,运行机制和原生CPython一模一样。换句话说,你那些用了各种奇技淫巧的第三方库基本都能跑。
这玩意儿有多牛?
讲真,最直观的好处就是性能提升。官方用pystone跑分,Debian Python 2.7环境下,没编译的跑了13.7万分,用Nuitka加LTO优化后直接飙到46万分——快了差不多3.4倍。当然,不是所有代码都能加速这么多,但大部分场景下你肯定能感觉到。
更爽的是它生成的可执行文件是独立的。用 --mode=standalone 搞出来的文件夹,拷贝到没有Python环境的机器上照样跑。--mode=onefile 还能打包成单个exe,虽然启动会解压慢一丢丢,但分发起来太省心了。
上手难不难?
需要先装个C编译器。在Windows上,Nuitka会贴心地问你要不要自动下载MinGW64,点“是”就行。如果你装了Visual Studio,它也会优先用VS。Linux/macOS就用gcc或clang。
基本用法超简单:
python -m nuitka --follow-imports your_script.py
加 --follow-imports 会把所有依赖模块都编译进去,不然只编译主文件。要生成独立目录就加 --mode=standalone,要单文件就 --mode=onefile。
| 模式 |
命令示例 |
输出 |
适用场景 |
| 普通编译 |
nuitka script.py |
单个可执行文件(依赖本地Python) |
本地加速 |
| 独立模式 |
nuitka --mode=standalone script.py |
包含所有依赖的文件夹 |
分发到其他机器 |
| 单文件模式 |
nuitka --mode=onefile script.py |
单个exe启动包 |
分发方便,启动稍慢 |
| 模块模式 |
nuitka --mode=module some_module.py |
.so或.pyd扩展模块 |
替代源码模块 |
踩过的坑,提前告诉你
第一次用Nuitka编译一个带PyQt的项目,兴冲冲生成exe发给朋友,结果在他电脑上闪退——data文件没带进去。后来才知道,要用 --include-data-dir 或者 --include-package-data 把资源文件包进去。
还有个经典坑:fork炸弹。有些库(比如multiprocessing)会在子进程里重新调用 sys.executable,而你编出来的exe再调用自己没处理好就递归爆炸。Nuitka默认有个防护,但如果你确定没问题,可以加 --no-deployment-flag=self-execution 关掉。
另外在Windows上,编译时最好把输出文件夹加到Windows Defender的排除列表里,否则实时扫描锁住文件导致编译失败——别问我怎么知道的,试了一下午才找到原因。
几个让编译更快的小技巧
装个 ccache(Windows上Nuitka会自动下载),重复编译会快很多。还有,用 python -m nuitka 而不是直接敲 nuitka,能确保用的Python解释器和编译器版本匹配,省得出现莫名其妙的错误。
我习惯把Nuitka的选项直接写在代码开头的注释里,像这样:
# nuitka-project: --mode=standalone
# nuitka-project: --enable-plugin=pyside2
# nuitka-project: --include-data-files={MAIN_DIRECTORY}/icon.png=icon.png
这样以后自己都忘不了要加哪些参数,超级方便。
写在最后
Nuitka确实是个良心项目,AGPL协议开源,但也提供了商用版(主要在技术支持和服务上)。如果你厌倦了打包工具的玄学问题,不妨试试这个编译器路线。反正我用了之后,再也没为打包发过愁。
项目地址:https://github.com/Nuitka/Nuitka