你需要知道的
uv 是一个非常强大的工具,可以工程化一个python项目,而不只是作为一个虚拟环境管理工具。1
🚀 一个工具替代 pip、pip-tools、pipx、poetry、pyenv、twine、virtualenv 等
⚡️ 比 pip 快 10-100 倍
🗂️ 提供全面的项目管理功能,包含通用锁文件
❇️ 运行脚本,支持内联依赖元数据
🐍 安装和管理 Python 版本
🛠️ 运行和安装 以 Python 包形式发布的工具
🔩 包含 pip 兼容接口,在熟悉 CLI 的同时获得性能提升
🏢 支持 Cargo 风格的工作区用于可扩展项目
💾 磁盘空间高效,通过全局缓存实现依赖去重
⏬ 无需 Rust 或 Python 即可通过 curl 或 pip 安装
🖥️ 支持 macOS、Linux 和 Windows
在此以写一个项目的方式来介绍一下uv的使用方法,当然了,uv的功能远不止这些。
安装UV
安装uv非常简单,可以通过pip安装:
| |
然而这种方法并不推荐,因为它会将uv安装在全局环境中,可能会导致版本冲突和权限问题。
uv官方提供了二进制版本,可以一键安装
- linux/MacOS:
curl -LsSf https://astral.sh/uv/install.sh | sh - windows:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
这时,你可能需要将uv添加到path中,别担心,uv会提示你如何操作。
使用UV
使用uv创建一个python项目
在你想要创建项目的目录下,运行以下命令:
| |
可以看到,uv会在文件夹下自动帮你初始化一个项目,包含git,pyproject.toml,uv.lock等文件。
运行项目
如果你运行python ./main.py,你就会收到uv的问候。
在 main.py,或是 src 目录下的其他 Python 文件中,你可以开始编写你的项目代码了。
添加依赖
在我们coding过程中,通常需要添加一些第三方的依赖,如httpx,我们可以直接在代码中添加依赖:
| |
此时,uv做了以下事情
- 自动为你创建虚拟环境到.venv下
- 安装httpx到虚拟环境中
- 将httpx添加到pyproject.toml的dependencies中
- 将httpx添加到uv.lock中
运行程序
在上文中,我们使用python ./main.py来运行项目,但是事实上我们这里使用的是全局的python解释器,而不是uv创建的虚拟环境中的python解释器。
因此,我们需要使用.venv中的python解释器来运行项目:
| |
这样,uv会自动使用.venv中的python解释器来运行main.py,并且会自动加载项目的依赖。 如果需要手动进入虚拟环境中,你需要手动激活
- windows:
.venv\Scripts\activate - linux/MacOS:
source .venv/bin/activate
此时终端的上下文已经切换到虚拟环境中,你可以直接使用python来运行项目了。
| |
手动同步
在一些情况下,我们可能使用uv pip install来安装了一些包,但是uv并不会自动将这些包添加到pyproject.toml和uv.lock中,此时可能会导致pyproject.toml和uv.lock中的依赖和实际安装的依赖不一致,最终导致项目无法运行。
因此,我们需要手动同步镜像,方法如下:
| |
此命令会将pyproject.toml和uv.lock中的依赖同步到虚拟环境中,确保项目的依赖和实际安装的依赖一致。
一些常见的问题
uv pip 和 pip 的区别
事实上,pip 也只是 Python 的一个包,而不是独立的组件。你甚至可以使用 pip 来安装 pip!
而 uv pip 是 uv 重写的 pip,具有 pip 的功能,但更高效。同时,uv pip 会自动使用当前项目下的虚拟环境来安装依赖,而不是全局环境。
为什么我使用uv创建了虚拟环境,但是在环境里用pip安装的包却失踪了
正如上文所述,pip只是python的一个包,而不是独立的组件。当你在uv创建的虚拟环境中时,由于uv并不会一并安装pip等组件,导致你在虚拟环境中使用pip其实是全局环境中的pip,自然而然,你安装的包就会安装在全局环境中,而不是虚拟环境中。
为什么我的pip包下载速度这么慢
uv并不会使用你系统设置的pip的pypi索引,因此你需要自行为uv设置一个pypi索引,方法如下:
为项目使用单独的pypi索引
在你的项目的pyproject.toml中添加以下内容:
| |
设置全局的pypi索引
Windows
按下 Win + R,输入 %APPDATA%\uv\uv.toml,回车后在打开的文件中添加以下内容:
| |
Linux/MacOS
在你的用户目录下创建一个uv文件夹,在该文件夹下创建一个uv.toml文件,添加以下内容:
| |
我为什么要使用UV
uv解决了以下问题
全局环境冲突
在开发两个不同的项目时,可能会出现两个项目依赖的库版本不兼容的情况。 比如项目A 需要pydantic 2.0,而项目B 需要pydantic 3.0,这时如果直接安装在全局环境中,就会导致冲突,无法同时满足两个项目的需求。
后来出现了虚拟环境工具(如 virtualenv、venv),可以为每个项目创建一个独立的环境,避免了全局环境冲突的问题。但是这些工具在管理依赖和版本方面仍然存在一些不足,比如需要手动激活环境、安装依赖等。
python 的虚空依赖
pip 是 Python 的包管理工具,他很好用。但是如果形成了下列的依赖链条
| |
当我们安装 A 时,pip 会自动安装 B、C、D 这三个依赖包。 但是当我们卸载 A 时,pip 只会卸载 A,而不会自动卸载 B、C、D 这三个依赖包。 这就导致了所谓的「虚空依赖」,即一些包被安装了但没有被任何项目依赖,最终占用磁盘空间。
项目化
在以往,经常会碰见一个.py文件就是一个项目的情况,很难声明这个项目需要哪些依赖,或者说这个项目需要什么样的环境。
后来有了 requirements.txt,可以声明项目的依赖,但是这个文件只能声明依赖的名称和版本,无法声明依赖的来源、安装方式等信息。
