关于PyInstaller
将程序运行需要的包和解释器打包起来。
官方文档:https://pyinstaller.readthedocs.io/en/stable/requirements.html
打包到一个文件夹
pyinstaller main.py
打包成一个可执行文件
运行时会创建一个临时文件夹,将需要的包复制到临时文件夹中,因此稍慢一些,正常结束时会自动删除,异常结束可能不会删除临时文件夹。
pyinstaller --onefile main.py # pyinstaller -F main.py
pyinstaller --onefile --windowed main.py # 窗口应用
隐藏源代码
打包的应用不包含任何源代码,不过编译成pyc文件,可以被反编译暴露代码逻辑。
如果想更彻底的隐藏源代码,使用CPython编译,再用pyinstaller打包。
pyinstaller还可以对python字节码进行加密,不过也可以被轻易得到秘钥解密得到字节码。
如何使用
执行pyinstaller main.py
,在当前目录自动建立两个目录build
和dist
,还生成了一个main.spec
文件。其中build
放了build日志和duild过程中需要的文件,dist
中放了打包的包和生成的可执行文件。main.spec
后面会仔细讲。
UPX
UPX压缩可执行文件和库,使得更小。运行时动态解压。
加密python字节码
需要先安装PyCrypto模块,使用参数--key={16char}
多版本
在虚拟环境下pyinstaller
支持不同的python版本.
在不同虚拟机下pyinstaller
以支持不同的OS.
sepc文件
可用pyi-makespec main.py
命令生成spec文件,暂时不进行打包。
其中最长需要修改的就是datas
这个部分,可以将代码中用到的文件一起打包,例如datas=[('./data/1.img', './data/'), ('./model/detect.weights', '.')]
,格式是(相对于spec的路径,相对于可执行exe的路径)。不过好像打包之后手动复制过去也行。
Maximum recursion depth exceeded:
递归层数过深,可以通过在main.spec文件中添加以下两行代码解决
# -*- mode: python -*- import sys sys.setrecursionlimit(5000) #5000可根据情况修改
Cannot find existing PyQt5 plugin directories:
找不到PyQt5,这种情况可能你是用conda安装的PyQt5,重新用pip安装一下可以解决这个问题。
You may load I/O plugins with the skimage.io.use_plugin
command. A list of all available plugins can be found using skimage.io.plugins()
:
将main.spec中的相关地方修改成以下形式:
from PyInstaller.utils.hooks import collect_data_files, collect_submodules datas = collect_data_files("skimage.io._plugins") hiddenimports = collect_submodules('skimage.io._plugins')
实际打包过程中由于代码中使用的包不同可能还会碰到其它的问题,就需要自己去摸索了。
参考