赛博红兔的科技博客

CyberHongTu shares news, insights, and musings on fascinating technology subjects.


全面掌握UV:Python下一代环境管理懒人工具

大家好,欢迎回到“Python五分钟”,我是赛博红兔。先说这一期干货满满不止五分钟。在我们学习完Python基础知识开始尝试复刻别人项目或者创建自己新项目的时候,经常要用pip来下载一些模块和库,或者需要手动创建虚拟环境,结合requirements.txt文件来复刻或者记录环境里的用到所有库。最近我发现不少朋友对Python这种繁琐且反人类的环境管理方式大吐苦水。更是把requirements文件比作不能准确记录依赖关系,无法自动锁定库版本,不能智能升级和管理环境,可读性差,环境复现也不可靠的一坨。如果你也有类似的烦恼,今天我来给大伙介绍一种最近火热的uv环境管理懒人包。从它的主页来看,uv非常有野心啊,它想要取代 pip、poetry等等众多工具,而且速度是pip的10到100倍,可以管理Python版本和虚拟环境等等等等。我们一边学一边来看看它到底有多好用。

首先是uv的安装,官网介绍了很多种方法,最推荐的是官方本身的下载器:

  1. 如果是Window操作系统,可以直接在powershell命令窗口打下面这行命令:powershell -ExecutionPolicy ByPass -c “irm https://astral.sh/uv/install.ps1 | iex”
  2. Mac和Linux系统可以用这条命令:curl -LsSf https://astral.sh/uv/install.sh | sh

之后uv就会默认安装到这个路径:C:\Users\<你的用户名>\.local\bin。当然,也可以用传统的pip install uv来下载,但是可能会污染当前环境,所以不推荐。注意,如果我们想好要用uv这个工具了,那么就不要再去用传统的pip和虚拟环境工具了,以免污染环境。然后我们要确定uv是不是安装成功了,只需要在窗口打uv即可。如果可以看到一串uv的说明就算安装成功了。如果报错了,有可能是这个安装目录不在你的系统 PATH环境变量中,你需要手动添加进去。

有了uv之后,首先它支持多版本Python的安装和管理。uv python list可以看到所有可以下载的Python版本。可以看到我这里已经下载的版本还有存储的路径。我们可以用uv python install 加上你想安装的版本号来安装Python。再也不用去官网或者别的网页上下载Python了,而且下载速度非常快。因为uv是用Rust编写的而且使用的是多线程下载,比pip串行下载快上不少。我们可以用uv python pin 3.13来固定我们想用的Python版本。当然,uv python uninstall可以卸载某个Python版本。

接下来,我们直接用uv来建立一个项目。大家可以看到,我新建一个文件夹叫uv_demo。我们用uv init来初始化这个项目。大家可以看到,文件夹里创建了好多文件。如果有Git版本控制的话还会自动生成.gitignore文件。python-version文件是记录当前项目使用的Python版本。main.py是主Python脚本文件,当然我们可以修改或者添加别的脚本啊。pyproject.toml是项目配置和依赖声明,就类似requirements文件,但是更加的清晰和详细。有项目名称、项目版本号和项目介绍(这些你可以自己修改)、README项目说明文档、要求的 Python 版本(我们这里是至少3.13版本,你也可以设置成要求别这么高,稍旧一些的版本可以增加对别的库的兼容性。比如说>=3.10版本)。还有dependencies文件记录项目依赖的第三方库,可以手动添加或者用命令添加。是不是一目了然?最后还有这个uv.lock是一个锁定文件,用来锁定安装的库的精确版本,确保你和别人在使用这个项目的时候环境完全一致。这会很大程度上减少requirements.txt一类的传统环境管理不同版本的库的杂乱和冲突。我们后面还会提到。这么一看,uv就像是一个创建项目的懒人包。

我们如果想要创建一个虚拟环境,可以用uv venv。这时候就会自动生成venv的虚拟环境。我们就用它的默认的主程序脚本运行一下。我们用uv run main.py来运行主程序,用uv run这个命令之后,这里所有的文件,包括版本号,pyproject.toml还有uv.lock会自动地更新和锁定库文件,全是自动的。当然,大多时候我们需要往项目里导入第三方的模块和库,比如说我们导入numpy和pandas。运行之后,报错说找不到这两个库,因为我们还没有安装。我们用uv add命令来安装这些库,同时也把它们更新到了dependencies项目依赖里去了。我们也可以安装特定版本的库,比如说(uv add matplotlib==3.10.0)。注意,uv为了照顾老用户还是保留了uv pip install这样的指令,但是主要用来临时添加一个库。我上面也说了,用了uv就不要去用传统的pip还有虚拟环境,不然会污染环境。同时,uv.lock文件会自动从项目依赖解析出的完整的依赖图和每个库具体版本并且锁定。这意味着,只要有同一个uv.lock,任何人都能复刻出完全一样的环境。所以说,如果我们想要上传项目到Git的话,必须也要共享pyproject.toml和uv.lock这两个文件。我们现在可以用uv tree来看下项目用到的每个库的依赖关系树。比如说,我们可以清晰看到用了matplotlib,numpy和pandas三个库,而且matplotlib和pandas都已经包含了numpy整个库了。所以,我们可以用uv remove来删除numpy库。另外,我提一个uv的好处就是,每个项目的环境包都是完全独立的,但是uv在本地有一个全局缓存目录 (可以用uv cache dir查看),当另一个项目安装相同版本库的时候,uv会复用这些缓存文件,不需要再重新下载了。也就是说,等你以后再用到这些常用的库时几乎是秒装。

那么如果我们从比如说GitHub上或者哪里克隆来的别人用uv来管理的项目,我们怎么来复刻环境呢?那就非常简单了。我这里来演示一下,我们用Remove-Item -Recurse -Force .\.venv删除venv里所有环境文件。现在相当于我们从别的地方用不同的方法克隆的一个项目,因为有uv的pyproject.toml和uv.lock这两个文件,我们复刻环境只需要打uv sync这个命令就可以自动同步下载生成一模一样版本的环境文件了。当然也可以用uv从传统的requirements.txt来复刻环境。比如说,我们这里有一个requirements.txt文件,只需要打uv add -r requirements.txt就可以啦。

目前uv还在开发阶段,很多Python环境的痛点正在着手解决。以上差不多就是我对它主要功能的介绍了,怎么样,你觉得这个最近爆红的懒人包有希望改善你的工作流吗?至少对我来说,我打算给它一个机会。如果不合适,大不了删掉换回老办法也没啥损失,对吧?大伙也可以试试看,有什么感受、遇到什么问题,欢迎在评论区告诉我你们的体验。我是赛博红兔,咱们下期再见!



Leave a comment