Python 现代化打包应用到 exe 的方式?

LeeReamond1月前0

前一段时间看到 PyOxidizer 这个项目,但是大概看了看文档也没看懂,看起来似乎是个打包程序,但似乎要和 rust 关联,我想打包 python 程序为什么和 rust 产生关系了?

pyinstaller 打包方式已经持续多年了,比如一个简单的需求是,我有一个 main.py 的程序,有若干 pip 依赖,我现在希望产生一个 exe ,让它在没有安装 python 的电脑上也能运行。pyinstaller 能用,但是实在也说不上好用,隐藏源码之类的功能就不奢求了,打包完后提示缺少依赖也是常事,在加上启动速度实在不敢恭维。

py 虚拟机相对于 java 虚拟机启动起来还是要快一些,比如运行

python -c "print('hello world')"

这种命令无论在 win 还是 linux 上都可以 0.1 秒内返回结果。而 venv 之类的虚拟环境本身体积也不是很大,大概只有十几 MB ,为啥不能有个好用的打包系统。。。后来有个 nuitika 打包,但是还是使用起来不方便,我想随手发布个小脚本,打包还要 gcc 环境。。

最新回复 (17)
  • nexply19201月前
    引用2
    坐等大佬
  • ClericPy1月前
    引用3
    呃, 巧了... 我今晚上刚发出去一个 GUI 帮着用 nuitka 打包的, 拖延了一年多昨晚上整理 GTD 时候看到
    代码质量很渣, 也就是个能用的原型阶段, 可以参考一下, 主要就是记不住那么多参数和文档, 以及依赖源码分离打包
    https://github.com/ClericPy/nuitka_simple_gui
  • lifansama1月前
    引用4
    @ClericPy 能请教一个问题吗,--nofollow-imports 的作用是什么?在 nuitka 的 User Manual 里没有找到这个参数
  • ClericPy1月前
    引用5
    @lifansama 为了依赖和源码分离, 依赖我通过 pip install -t xxx 的方式直接丢进去, 不然编译太久了, 之前编译 psutil 啥的没等死我...
  • jeeyong1月前
    引用6
    我一直用 pyinstaller 打包的啊..
    如果你都打包到一个文件里, 启动速度就会慢. 他要先解压缩到一个系统临时目录.
    不用-F 参数, 就没啥事啊..
    至于缺少依赖的事情...有几个参数可以快速打包好.
    我发布过的最复杂的应用是打包 chromium, requests, pyqt, pymysql, xpinyin, cchardet, pyquery, win32api, psutil.
    总共 800 多 MB
  • saucerman81月前
    引用7
    @jeeyong #5 我之前用 pyinstall 打包一个 flask 写的最简单的 web app ,启动特别慢,用不用-F 都很慢,不知道为啥。。后来放弃了
  • Buges1月前
    引用8
    是的,Python 打包很难用。你费半天劲打包好了,扔 musl 的发行版上一跑,还是跑不起来。
    我更希望 Python 能有类似前端 webpack/rollup 那样的打包,能把代码包括依赖 bundle 起来,并 transpile 到兼容低版本运行环境的代码。要是还能妥善处理 native 依赖(按需安装或构建)就更好了。
  • makelove1月前
    引用9
    折腾这个不如换个真编译语言,学个 go 也就三天功夫就能开写,你找完美打包可能也要这么长时间别提还不是完美方案
  • pursuer1月前
    引用10
    python 设计时就更倾向于模块复用,不怎么考虑打包。还是让用户 pip install -r requirements.txt 吧 。如果用户不会,那说明他不是你的目标用户吧(玩笑
  • Osk1月前
    引用11
    如果是 Windows, 也许考虑下 python embedded zip 版本, 此版本没有带 tk 等 GUI, 我没尝试过安装.
    用 embedded zip 版, 先改一点配置, 并安装上 pip, 然后, pip 安装依赖.
    接下来, 直接使用这个 python 环境进行开发. 等要发布正式版本时, 将 site-packages 压缩成 zip (可选, 压缩的好处是减少小文件, 节省体积), 写个 bootstrap 脚本(cmd/bat), 调用这个 python 执行自己的脚本即可.
    如果有需要, 可以将自己的源代码编译成 pyc, 项目的依赖也可以编译后压缩成 zip.
    最终, 依赖引入配置里面包含:
    python.zip: 嵌入发行版自带的标准库 zip.
    site.zip : pip 安装的第三方依赖, 自行打包 zip.
    project_deps.zip : 项目依赖, 自行打包.
    好处是: 真的不会有依赖问题.
    缺点是: 文件相对比大一点, 且不是一个 exe (虽然你可以用 rar 等工具创建 sfx), bootstrap 脚本需要一点 cmd 脚本知识, 没写好容易启动不了(比如空格等问题).
    至于 linux: 告辞, 生态碎成渣, 没有, 不然也就不会出现 docker, snap, flatpak 等奇奇怪怪的东西了
  • jeeyong1月前
    引用12
    @saucerman8 哦? 我试试
  • fuis1月前
    引用13
    https://github.com/indygreg/PyOxidizer
  • stefwoo1月前
    引用14
    我感觉弄成 docker 还简单点。
  • libaili1月前
    引用15
    @stefwoo 说的不是一回事,docker 多用于服务端,楼主说的是客户端
  • ClericPy1月前
    引用16
    看到楼主提到 venv, 如果客户端那边有 python 解释器, 可以考虑走 zipapp + zipimport 的路子, 目前我平时用的就是 shiv 和我自己写的 zipapps, 貌似还有个 pex
    https://github.com/ClericPy/zipapps
    zipapps 几个参数可以注意一下, 也勉强能用来发布客户端:
    0. 如果对方没有 python 解释器, 也可以用官网那个 embed 嵌入式的绿色版解释器, 不过 -p 的 shebang 似乎只对 pylauncher 那个有用, 得自己写个启动 bat
    1. -o 的时候后缀把 .pyz 改成 .py, 这样子 Windows 上只要双击就行了
    2. -u=* 这样会把所有代码都解压出来, 避免一些相对路径导入的问题, 或者动态链接库的导入问题, 或者 -u=AUTO 自动判断 .pyd 如果不存在就不解压了
    3. -d 这个参数是在运行的时候安装依赖, 一开始是用来做跨平台发布(因为只和客户端有关), 而且节省打包后的 zip 大小, 并且依赖没变的话不会重新安装. 不过鉴于 embed python 没有 pip, 还要配合 ensure pip 参数, 有点麻烦, 当然如果对方是官网的 python 解释器自带 pip 就没事
    4. 当然如果对方不但有 venv 也可以直接用里面的 python.exe 来执行 pyz 文件, 依赖就不用打了
    不过多数情况还是拿来云原生上发布使用, 今天写 nuitka 那个 GUI 就是为了取代 zipapps 的习惯
  • PMR1月前
    引用17
    用 cy 编译下 在用 pyinstaller 打包 不打包单文件速度还行 就单文件解压要时间
  • 6109155181月前
    引用18
    打包成单文件的话启动的确会慢些,试试 pyinstaller xx.py ,不带 -F 参数。缺少依赖就缺啥补啥,其实可以玩玩 go 语言,开发一些小脚本也是很快的
  • 游客
    19
返回