我们有时候经常会使用python写一些小工具,在Linux环境下可以很方便运行,因为Linux默认都会有python环境,我们只需要添加python脚本依赖的类库即可执行。但是有的时候我们需要把小工具给到一些麻瓜去用的时候就会出现一些问题,他们大多是在Windows上运行工具,那就必须要先准备python的可运行环境才行,这就给麻瓜们带来了使用成本,我们能否将python脚本打包成windows下可执行文件呢?

接下来让我们先了解一下python有哪些类库可以帮助我们解决这个问题。

这是一个来自Freezing Your Code的统计

Solution Windows Linux OS X Python 3 License One-file mode Zipfile import Eggs pkg_resources support
bbFreeze yes yes yes no MIT no yes yes yes
py2exe yes no no yes MIT yes yes no no
pyInstaller yes yes yes yes GPL yes no yes no
cx_Freeze yes yes yes yes PSF no yes yes no
py2app no no yes yes MIT no yes yes yes

我们能看到有很多类库都可以解决我们的问题,其中pyInstallercx_FreezebbFreeze都不错,pkg_resources新版的pyInstaller貌似是支持的。

我们这里选用pyInstaller尝试一下,因为它各方面支持的是最好的。

PyInstaller原理介绍

PyInstaller其实就是把python解析器和脚本以及脚本的依赖库打包成一个可执行的文件,这和编译成真正的机器码是两回事,所以通过PyInstaller打包成一个可执行文件可能不会提高运行效率,相反可能会降低运行效率,但是它带来的好处就是在运行者的机器上不用安装python和你的脚本依赖的库。在Linux操作系统下,它主要用的binutil工具包里面的lddobjdump命令。

PyInstaller输入你指定的的脚本,首先分析脚本所依赖的其他脚本,然后去查找,复制,把所有相关的脚本收集起来,包括Python解析器,然后把这些文件放在一个目录下,再打包进一个可执行文件里。

这样就可以直接发布输出整个文件夹里面的文件,或者生成可执行文件。你只需要告诉用户,你的App是自我包含的,不需要安装其他包,或某个版本的Python,就可以直接运行。

但是需要注意的是,PyInstaller打包的执行文件,只能在和打包机器系统同样的环境下运行。它不具备可移植性,若需要在不同系统上运行,就必须针对不同平台进行打包。

安装PyInstaller

网络情况可以的话使用pip安装还是很方便的。

pip install pyinstaller

如果网络不稳定,尤其在天朝访问墙外站点是很痛苦的,我们还可以通过下载源码包来安装。

# 在源码包的根目录下执行
python setup.py install

安装完成后,检查安装版本。

pyinstaller --version

使用PyInstaller进行打包

pyinstaller的语法

pyinstaller [options] script [script ...] | specfile

具体命令如何使用可以通过help或官方文档去查询具体的用法。

我这里只说几个注意的点。

-F, --onefile Create a one-file bundled executable.创建一个可执行文件

-w, --windowed, --noconsole去除黑框

# A path to search for imports (like using PYTHONPATH). Multiple paths are allowed, separated by ‘:’, or use this option multiple times

-p DIR, --paths DIR

设置一个可搜索的入口路径,怎么理解呢?如果不指定这个参数打包出来的文件只能在生成它的目录下运行,如果打包时指定参数为-p .打包出来的文件可以放在任意路径下运行,如下示例:

pyinstaller -w -F -p . your.py

参考资料

到这里PyInstaller就简单介绍完毕,感兴趣的可以试一试,我以前使用的是py2exe,其实py2exe也蛮好只不过它需要创建一个py脚本来把需要打包的脚本包含进去,用起来没有PyInstaller方便,希望这个简单的入门可以帮助到需要的朋友。

Keep Real!