PyInstaller是一个十分有用的第三方库,通过将py文件打包,Python程序可以在没有安装 Python的环境中运行,也可以作为一个独立文件方便传递和管理。

 

安装方法

pip install PyInstaller

或者官网下载安装。

 

使用

使用下载安装的方式安装的Pyinstaller打包方式

将需要打包的文件放在解压得到的Pyinstaller文件夹中,打开cmd窗口,把路径cd到当前路径打开命令提示行,输入以下内容(最后的是要打包的py文件):

python pyinstaller.py -F myfile.py

 

使用pip方式安装的Pyinstaller打包方式

打开cmd窗口,cd切换到文件所在路径,输入以下内容(最后的是要打包的py文件):

pyinstaller -F myfile.py

 

参数

  • -F/–onfile           表示生成单个可执行文件。
  • -D/–onedir         表示生成一个程序文件夹。
  • -c/–console        表示运行时显示控制台窗口,默认参数不需要加。
  • -w/–windowed   表示去掉控制台窗口,这在GUI界面时非常有用,如果是命令行程序的话不要加这个选项。
  • -p 表示自己自定义需要加载的类路径,防止有库找不到,一般情况下用不到。
  • -n/–name       打包好的入口程序的名称。
  • -y/–noconfirm    无需确认即可覆盖输出目录中的文件。
  • –distpath        输出路径,打包好的程序的存放路径,默认为/dist。
  • –workpath      工作路径,用于存放打包过程中的临时文件,默认为当前路径。
  • -i/–icon           打包好的可执行文件的图标。
  • –key    用于加密Python字节码的密钥,此功能在内部使用tinyaes模块进行加密,不能与VmProtect等加壳工具一起使用。
  • –clean     打包前清理缓存和临时文件
  • –add-data=”image.png:img”       额外需要打包进去的文件,例如图片、文档等。
  • –add-binary=”libfo.so:lib”    额外需要打包进去的二进制文件,例如dll等。
  • –uac-admin      打包好的程序执行时会要求管理员权限。

 

注意事项

即使将py脚本打包成exe程序,也不意味着代码的安全性很高,例如可以通过pyinstxtractor进行提取和Uncompyle6进行反编译,因此要想有效保证代码安全,还得考虑混淆和加壳等手段。

另外注意的是,打包出的exe可执行文件或者程序包体积会偏大,为降低体积可以在编写程序时尽量不要导入用不到的库,需要的库用到什么功能就只导入什么功能。也就是说尽量不要用import XX而是用from XX import YY。

打包出的程序如果在运行时闪退,如果确认程序本身没问题,那么可能是系统缺少C++或者.net framework等运行库。

 

关于打包太多库的优化

由于我用的anaconda包管理,因此不可避免会在打包时打包进无关的库,导致程序包体积变大,因此下面说一下优化方法。

  • 使用pycharm等IDE的venv功能,在全新的Python虚拟环境中只安装自己用到的库和pyinstaller,并在这个虚拟环境中打包。
  • 使用pipenv安装虚拟环境和第三方库,再进行打包,具体如下。

由于只能打包成exe,因此只能在windows环境下使用。

另外注意的是,打包出的exe可执行文件或者程序包体积会偏大,为降低体积可以在编写程序时尽量不要导入用不到的库,需要的库用到什么功能就只导入什么功能。也就是说尽量不要用import XX而是用from XX import YY。

pip install pipenv             #安装
pipenv install --python 3.7    #选择Python版本
pipenv shell                   #进入新建的虚拟环境
pip list                       #展示已安装的库,应该只有几个自带的库
pipenv install pyqt5           #安装用到的库

以上两个方法都是通过虚拟一个干净的Python环境打包,但有时会遇到使用的库有很多依赖库造成打包体积偏大,下面两个方法可以进行尝试。

  • 如果只用到了一个库里的个别方法,可以尝试将该段代码直接复制到自己脚本上,当成自己写的方法进行调用。需要注意的是复制过来的代码中有没有其他引用,有的话要一并复制过来。
  • 如果以上方法都不管用,那还有最后一个笨方法,直接删。比如说我用到了pandas库读取csv文件的功能,它会把numpy等依赖库一并打包,打包后文件包大小超过了700M。

经过删除某些dll文件并运行测试,在删除掉一些确实用不到的文件后,打包后的文件包降到了100M,当然这个方法要仔细测试,避免删掉了必要的dll导致某些功能失效。

 


成长就是妥协与坚持的两难。

《解忧杂货店》
——东野圭吾