比较PyInstaller和Nuitka

作为一名写过《PyInstaller打包实战指南》《Nuitka打包实战指南》的博主,笔者觉得自己还是有必要写一下这两个打包库的对比分析,好让大家直观地了解到它们之间的异同点和优劣点。

笔者将从以下几个方面进行对比:

Python版本兼容性

跨平台性

文档

流行度

安全性

打包速度

报错解决

打包大小

打包后的启动速度


Python版本兼容性

PyInstaller最新版本 (目前是4.8) 支持Python3.6-3.10。Nuitka最新版本(目前是0.6.19)支持Python2.6-2.7和Python3.3-3.10。

跨平台性

PyInstaller和Nuitka都能在Windows、MacOS和Linxu系统上进行打包操作,并生成相应平台的可执行文件。

文档

PyInstaller文档Nuitka文档更加详细,条理性要更胜一筹。Nuitka文档中写的英语不是很标准,有语法错误,有时候会比较难看懂作者想要表达的意思 (作者本人不是以英语为母语的,所以可以理解吧)。

流行度

PyInstaller出来时间比Nuitka早,在国内流行程度也比较高 (国外不清楚)。通过百度搜索的结果数量可以知道目前PyInstaller被使用地更多。当然光从这一点上比较会不准确,大家可以从其他平台搜索结果上再比较下。

比较PyInstaller和Nuitka

比较PyInstaller和Nuitka

安全性

PyInstaller在打包时将py文件编译成pyc文件,这个可以直接被反编译。你也可以通过--key命令在打包时进行加密,但也不安全。如果要做到更高程度的安全性,可以结合Cython来加密打包。Nutka是直接将py文件编译成c语言级别的文件,安全性上面更胜一筹。

打包速度

对于简单的程序,两者的打包速度都是差不多的。不过碰到一个相对来说较大的库时,Nuitka会去编译这个库,导致它的打包速度非常非常非常地慢。当然,第三方库的代码是不需要加密的,所以我们可以通过--nofollow-imports命令不编译引入的库,通过--include-data-dir命令直接复制进来(当然你也可以后期手动复制)。PyInstaller默认是直接复制进来的,不会进行编译。

报错解决

最常见的报错其实是ModuleNotFoundError,也就是找不到相应库或模块。这个其实是比较基础的报错,解决方法就是找到相应的库或模块,打包进去就可以。PyInstaller用--hidden-import解决,Nuitka用--include-package或--include-module解决。如果上面的命令都解决不掉,那就手动复制下。如果手动复制能够解决掉,那么重新打包时可以用--add-data(PyInstaller上的)或者--include-data-dir和--include-data-file(Nuitka上的)命令直接将相应库或模块打包进去。

另外从上面的流行度比较可以看出,PyInstaller目前的报错解决方案是更多的,毕竟Nuitka也才刚刚兴起。

打包大小

相信是大家都比较关心这一点。我们需要明确的一点是,PyInstaller和Nuitka都有单文件和多文件打包模式,也就是打包成一个可执行文件和一个文件夹。一个误区就是,很多人把多文件模式打包后的exe同单文件打包模式后的exe进行比较。单文件打包模式把所有的依赖文件都放到了一个可执行文件中,而多文件模式是把依赖文件同可执行文件一起放在一个文件夹下的,所以单文件打包模式生成的可执行文件必然会大很多,两种打包模式后生成的可执行文件大小没有可比性。

要比的话肯定是在相同打包模式下进行比较,也就是说pyinstaller -F跟nuitka --onefile比,或者pyinstaller -D跟nuitka --standalone比。笔者就不进行打包演示了,因为单在笔者自己电脑上的打包拿来作示例的话不够令人信服,请读者自己进行尝试。

不过不论是PyInstaller和Nuitka,在Windows上打包时都可以用UPX进行压缩。在PyInstaller上我们可以用--exclude-module命令排除掉不必要的引入模块,从而减少包体大小。在Nuitka上使用--onefile命令打包时,zstandard模块可以帮你减少包体大小。

打包后的启动速度

跟在上面的打包大小一节中讲的一样,不要拿多文件打包模式和单文件打包模式来比较,要比就比一样的。笔者在《PyInstaller打包实战指南》《Nuitka打包实战指南》中都写过单文件打包模式下可执行文件的运行原理——都会先花时间把依赖文件解压到临时文件夹下,然后再启动主程序。如果是多文件打包模式,依赖已经在文件夹下了,那么可执行文件运行也就不会再先花时间解压,而是直接启动主程序。

笔者看到网上很多说Nuitka启动速度比PyInstaller快很多的,多半是犯了上面这个错误。其实启动速度从人眼角度来看的话不会相差很多,当然从毫秒计时上来看,Nuitka还是有优势的,毕竟是编译成了C。

同样,读者可以自行尝试,这样更有说服力。

如果读者还想要看其他方面的比较,可以留言评论或者私信。笔者水平有限,如果文章有错误之处,还请指正。

上一篇:pycharm+Django启动我的第一个页面(Django二)


下一篇:python中pyinstaller模块使用方法