1 发布到 pypi
setup.py 这套东西已经很成熟了, 不再赘述, 当前主流的是 twine + wheel 的方式, 好处很简单, 就是 pip install 安装方式省心省力目前也比较流行 poetry 这个库的 publish 功能进行发布
2 作为 pyz 发布
Shiv
有 PEP441 的加成, 目前 Shiv 在这方面做的已经非常熟练了:
- 通过 pip 收集所需要的第三方库
- 通过 shebang 来指定 Python 解释器路径
- 通过 zipapp 相关功能把整个 package 打包成一个 pyz 压缩文件(实质是zip文件换了个扩展名)
- 通过 _bootstrap 指定执行条件 module:app
- 通过命令行执行整个打包过程
优点:
- 单文件上传下载简单方便
- 可以直接使用 python xxx.pyz 来执行 package 里的 main.py
- 也可以将 xxx.pyz 当作一个环境, 来执行其它的 py 脚本, 比如 python xxx.pyz a.py
- 省去了重新 pip 下载编译的过程, 而且也避免了缺少编译环境而无法安装 C 扩展, 即在打包机编译, 在生产环境直接执行
- 对于纯 Python 的依赖, 可以跨多个平台使用, 配合 shebang 更省去了查找解释器路径的过程
- 如果在 Windows 系统, 可以使用官方的嵌入式(embed)Python作为绿色版解释器一起打包, 省去了安装环境的过程
- pyz 文件在内存里解压, 不会额外占用临时文件夹的空间 (不确定)
缺点:
- 在不同操作系统打包的时候, 如果遇到需要编译的基于 C 语言的库, 编译出的环境不能通用
- 依然离不开解释器
- 对于
__file__
这种内置变量, 可能会导致定位内部某个文件路径时出问题
傻瓜式 pyz 打包从开始到放弃
曾想过写一个 GUI 来搞定打包 pyz 应用的整个过程
- 选择 module 路径
- 选择执行方式
- 安装 pip requirements
- 对 Python3.7+ 版本开启压缩选项
- 自动包装
__main__.py
- 对 Windows 系统支持去官网下载 embed 的解释器
- 选择 Python shebang, 可以支持上述 embed 解释器的相对路径一起打包
花 2 天折腾了几部分感觉吃力不讨好, 而且也不是什么急切的需要, 就搁置到一边了, 就算有急切需要, 平时 shiv 打包的已经足够好用, 所以 GUI 不是太着急用到
3 Windows 可执行程序
早年间 pyinstaller 因为不太成熟, 所以用的是 cx_freeze, 此外还有 py2app py2exe 之类的打包工具, 当时也有各种缺少头文件或环境依赖文件的 issue 要自己手动修复, 尤其是 pyqt 这种需要大量编译的情况2019 年来说, pyinstaller 已经非常成熟了, 而且文档也比较短, 所以基本只使用这个工具, 就可以满足绝大多数日常需要了
pyinstaller 的优点
- 文档简洁, 功能不复杂, 主要操作的参数也都一看就懂
- 不需要指定依赖的第三方库列表, 只要环境可以成功运行, 就会自动打包起来
- 支持多个平台打包 exe
- 打包速度比较快, 可以一起打包一些二进制文件或者其它类型的素材
- 支持单文件, 压缩, icon 等常用功能
pyinstaller 的缺点
- 单文件打包的时候, 要注意执行的时候如果不是正常退出(比如直接杀死进程, 或者抛错), 会导致临时目录里的冗余文件在执行以后无法自动清理掉, 因为它的实现原理就是解压缩到临时文件夹下来执行的; 不过一般如果使用的是 GUI 程序, 这种问题遇到的较少, 因为大多数 GUI 程序的关闭不是直接杀死进程, 而是关闭窗口
- 有些隐藏的问题会导致打包卡住, 比如 icon 不合法
- 如果在全局环境直接打包, 会打包一大堆多余的库进来. 解决方法是在虚拟环境里面打包, 对此, 之前我实现了一个Pyinstaller terminal UI 可以比较傻瓜式地按步骤打包, 创建的临时虚拟环境也可以打包完随手删掉
通过 PyinstallerUI 简化打包流程
pip install pyinstallerui -U
具体文档参考 https://github.com/ClericPy/pyinstallerui其实主要解决的问题是:
- 傻瓜式 UI 操作避免背命令行参数
- 在终端拖拽方式省去复制粘贴文件路径
- checkbox 方式通过多选开关一些功能参数
- 创建和删除临时虚拟环境, 避免打包时全局环境的库一起被打包, 浪费空间
- 一般专用虚拟环境下打包一些纯 Python 依赖的应用, 占用空间 9MB 左右
- 自动安装缺失的 pip 环境
- 打包前可以先执行测试, 避免打包完发现无法使用
- 打包完毕后自动清理垃圾文件
小结
现实中生产环境下的 deploy 却很少用到, 虽然 shiv 是 linkedin 以前挺喜欢的打包发布方式吧. 现在生产环境的发布, 大都走了主流的 CI/CD 套件, 有 docker 或者 gitflow 加成, 更稳定高效.所以, 以上就是闲聊的方式回顾一下之前用到的打包方式, 也是平时玩乐脚本分享给他人会用一下