[真跨平台] Python 打包新思路 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Tanix2
V2EX    Python

[真跨平台] Python 打包新思路

  •  
  •   Tanix2 139 天前 5174 次点击
    这是一个创建于 139 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近 Python 环境管理从 conda 切换到了uv,找到之前用 cargo 的感觉了,真爽。

    我发现 uv 可以下载独立的 Python ,非常感兴趣,因为之前经常使用 Embedded Python 打包东西。Embedded Python 只支持 Windows ,而 uv 支持 Windows/Linux/MacOS 。

    同时我又遇见了一个很 amazing 的项目,叫cosmopolitan,它可以将 C/C++编译为一种叫APE的格式的文件,这种神奇的格式同时满足多种文件格式,因此它可以在大多数主流的平台上运行。

    受以上两个项目启发,pyfuze 诞生了。它可以将你的 Python 项目打包,使其可以在大多数主流平台上运行。pyfuze 跨平台的逻辑是这样的:

    • pyfuze APE 作为启动器,检测当前平台是 Windows 还是 Unix ,下载对应 uv
    • uv 下载当前平台的 Python 以及项目依赖
    • uv run 运行源代码

    项目缺点是需要网络下载东西,不过你可以运行一下再打包,但这样就固定在你运行的平台了。

    截至目前,pyfuze 项目已获得 25 颗星,是我获得 star 最多的一个项目。如果你也喜欢这个项目,不妨也点颗:)

    P.S. uv 、python 、依赖都是从国外网络环境下载的,如需在国内网络环境下运行,需使用--env 、--uv-install-script-windows 以及--uv-install-script-unix 这三个选项,后两个选项支持使用文件路径。

    Star History Chart

    31 条回复    2025-06-03 12:30:38 +08:00
    LeeReamond
        1
    LeeReamond  
       139 天前
    虚拟环境最大一个问题是,比如我经常用 sublime text 这种基于系统默认环境的编辑器,启用虚拟环境解释器是很麻烦的事。uv 解决这个问题了吗?
    smallparking
        2
    smallparking  
       139 天前 via Android
    你这个其实也不是打包, 是下载 pytnon + 依赖库
    然后以源码形式运行 python
    Tanix2
        3
    Tanix2  
    OP
       139 天前
    @LeeReamond sublime text 我不太了解,我经常用 vscode/cursor ,uv 会创建.venv 文件夹,使用.venv/Scripts/python.exe 作为解释器就好了。
    Tanix2
        4
    Tanix2  
    OP
       139 天前
    @smallparking 可以直接执行,应该算打包的
    LeeReamond
        5
    LeeReamond  
       139 天前
    @Tanix2 所以就是执行这个指定目录的解释器,它的所有依赖就会指向对应的解释器环境是吧?那默认系统命令中的 python 怎么理解呢,是需要像 conda 一样激活环境才能使用 python 命令吗,还是 uv 不安装全局可运行的 python
    SenLief
        6
    SenLief  
       139 天前 via iPhone
    这是不是要每个包都下载一次 python
    passive
        7
    passive  
       139 天前 via Android   1
    “打包”的目的通常有:
    1. 不会操作计算机的小白客户开箱即用(楼主的方案遇到问题的风险有点大)
    2. 给内网机器用(这方案也不行)

    不过从 conda 换到 uv ,体验确实好了很多。
    cenyejinxi
        8
    cenyejinxi  
       139 天前
    @Tanix2 #5 你这个可以直接执行是执行的 pyfuze 阿 那为什么不直接下载对应平台的 python
    HTravel
        9
    HTravel  
       139 天前
    你这用起来这么麻烦,算什么打包。真打包必须支持所有依赖项全部打包进去。要做到好用基本上就要用 C++写起动器。像 Java jar 包启动时必须选择对应版本的 java 运行时,我就特意给 Java 写了引导器。不过我是分平台写的,windows 平台用汇编写的,macOS 用的 swift 。当然,实际上我的引导器功能不可能这么单一,还包括单例模式、以及设置进程最大运行时间,超时就杀掉。虽然最初是为 java 写的,但后来发现其实启动解释型代码的原理一样,也可以用于其他各种解释型语言(原生代码本就能自己启动也不需要解释器,当然如果为老的软件让其支持单例、最大运行时间包裹个引导器也没问题)。当然,我的方案不足之处是无法跨平台。除非再用 Qt 再外层再包裹一层,根据操作系统选择不同的引导器。

    你的还不如改 docker 算了,然后宣称完美跨了所有平台
    Alias4ck
        10
    Alias4ck   139 天前
    你这个不是要你的项目支持跨平台吗 只是一个 wrapper 啊 我要是写的 python c extension 咋办
    ronen
        11
    ronen  
       138 天前 via Android
    我公司刻了磁去甲方做,到了地一看大。完蛋
    sikong31
        12
    sikong31  
       138 天前
    @smallparking 不都是这样吗,打包成 exe 的依然是解压到临时目录运行
    smallparking
        13
    smallparking  
       138 天前 via Android
    @sikong31 我本意是 这个 pyfuze 打出的东西会在运行的时候下载一堆依赖。
    swordfeng
        14
    swordfeng  
       137 天前
    你这跟 pyinstaller 之类的打好然后做个下载器下载对应系统版本的运行有啥区别
    toan
        15
    toan  
       137 天前
    挺好,star 了
    iorilu
        16
    iorilu  
       137 天前
    uv 没代理装不了 python 得
    国内小白用不了

    打包就是为了给小白用的
    zwzwzwzwzxt
        17
    zwzwzwzwzxt  
       137 天前
    cosmopolitan 编译出来的可执行文件内嵌了个 zip, 程序里可以通过 `/zip/` 虚拟路径访问。所以理论上应该可以编译一个 cosmo 版本的 python 解释器,然后把所有依赖内嵌到 `/zip/` 下。

    其实官方给的 python demo 就是这么干的。不过考虑到第三方依赖的复杂性,可能要区分哪些是 pure python 库,哪些是带平台相关的依赖的
    zwzwzwzwzxt /td>
        18
    zwzwzwzwzxt  
       137 天前
    另外看到 OP 提到了 cargo, 不知道有没有尝试过用 Rust 开发 APE 项目?我最近在研究这个,发现除 Linux 外其他平台下的异步总有问题,哪怕用支持 poll 的 smol 也不行 = =
    cat9life
        19
    cat9life  
       136 天前
    统一上面提到的。打包的目的是什么?越改越复杂了,我还不如直接装一台运行环境?甚至 docker ?
    tairan2006
        20
    tairan2006  
       136 天前
    windows 环境用 pyinstaller ,其他环境用 docker 就行…

    好用还是 go build 这种
    Tanix2
        21
    Tanix2  
    OP
       136 天前
    @iorilu 目前的话国内 uv 的镜像有一些,但是不全。我写了个项目来建立 uv installer 、uv binary 、uv python 的镜像: https://github.com/TanixLu/uv_aliyun_mirror

    我部署了一个,使用方式:--uv-install-script-windows https://uv-mirror-fc-uv-mirr-service-qirrgrgrbr.cn-hangzhou.fcapp.run/uv-installer.ps1 --uv-install-script-unix https://uv-mirror-fc-uv-mirr-service-qirrgrgrbr.cn-hangzhou.fcapp.run/uv-installer.sh --env INSTALLER_DOWNLOAD_URL=https://uv-mirror-fc-uv-mirr-service-qirrgrgrbr.cn-hangzhou.fcapp.run --env UV_PYTHON_INSTALL_MIRROR=https://uv-mirror-fc-uv-mirr-service-qirrgrgrbr.cn-hangzhou.fcapp.run --env UV_DEFAULT_INDEX=https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/

    (最后一个选项是使用 pypi 清华源镜像)
    Tanix2
        22
    Tanix2  
    OP
       136 天前
    @cat9life 比方说你写了一个小工具要在多个环境上用;或者你写了一个小玩具想给朋友们分享,但是他们没有 python 环境。
    Tanix2
        23
    Tanix2  
    OP
       136 天前
    每个工具有它的优点和局限性,我这个工具的优点是跨平台,只用打包一次
    Tanix2
        24
    Tanix2  
    OP
       136 天前
    @zwzwzwzwzxt 我之前看到过相关的一篇文章,好像是不太好弄,rust 编译器有的东西是写死在里面的: https://ahgamut.github.io/2022/07/27/ape-rust-example/
    Tanix2
        25
    Tanix2  
    OP
       136 天前
    @tairan2006 那别人得有 docker 啊,要是用户没有 docker 怎么办?我这个的依赖可以说就一个网络。
    zwzwzwzwzxt
        26
    zwzwzwzwzxt  
       136 天前
    @Tanix2 #24 哈哈这个项目我有看,不知道是太老了还是 demo 太简单了,我遇到了一个大坑就是 LLVM 编译默认会插入栈保护代码,在 aarch64 下还会占用 `x28` 寄存器,导致莫名崩溃。好在这俩可以通过添加编译参数解决,目前没出现莫名崩溃的问题了。

    再一个坑就是标准库,某些操作直接走 syscall 没走 libc ,还有一些 flag 等参数值在其他平台上不兼容,必须得 patch 标准库。。
    BBBOND
        27
    BBBOND  
       136 天前
    还得是 pyinstaller
    Tanix2
        28
    Tanix2  
    OP
       136 天前
    @zwzwzwzwzxt 确实没研究过这方面,不了解了
    frostming
        29
    frostming  
       135 天前
    tomczhen
        30
    tomczhen  
       134 天前
    都要联网了,直接打包成 whl 然后 uvx 来运行应该更直接。
    Tanix2
        31
    Tanix2  
    OP
       128 天前
    @tomczhen 我研究研究
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3983 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 04:10 PVG 12:10 LAX 21:10 JFK 00:10
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86