在最早开始学习python的时候,用的还是最原始的pip intall xxx
,当时各种版本环境混乱不堪,后来开始学习一些机器学习和深度学习等方向的内容时,接触到了 Anaconda 来管理 Python 依赖,其实一开始还是比较爽歪歪的,但是后续随着使用的包越来越多也越来越杂,conda 的一些缺点也逐渐显露出来,conda 下的包覆盖度还是比较低的,大多数场景下还是会通过 pip 来拉取各种依赖包。直到前段时间在把玩 mcp 的时候,遇到了 mcp
团队在使用的 uv
工具。
什么是 uv
uv
是一个 python 生态下快速且野心勃勃的包管理工具,如果你是一名 Python 开发者,我相信你已经听说过非常多关于这个名为 uv
的包管理工具的讨论了。说实话,我对于新型工具还是持有一种非常谨慎的态度,从 npm
到 yarn
再到 pnpm
,其实还是比较保守的。但是我真的非常惬意的接受了 uv 的介入,唯一的槽点可能就是 PyCharm 的支持度不足。
那么 uv 到底是什么呢?
- 🚀 A single tool to replace
pip
,pip-tools
,pipx
,poetry
,pyenv
,twine
,virtualenv
, and more.- ⚡️ 10-100x faster than
pip
.- 🗂️ Provides comprehensive project management, with a universal lockfile.
- ❇️ Runs scripts, with support for inline dependency metadata.
- 🐍 Installs and manages Python versions.
- 🛠️ Runs and installs tools published as Python packages.
- 🔩 Includes a pip-compatible interface for a performance boost with a familiar CLI.
- 🏢 Supports Cargo-style workspaces for scalable projects.
- 💾 Disk-space efficient, with a global cache for dependency deduplication.
- ⏬ Installable without Rust or Python via
curl
orpip
.- 🖥️ Supports macOS, Linux, and Windows.
其实一句话概括一下,uv 可以取代你的任何 Python 依赖和环境管理工具,并且帮你做到更快且更好!
为什么选择 uv
- uv 的速度快的惊人
- uv 的功能补足你对 Python 包管理的所有幻想
- uv 的锈化带给未来更多可能
uv 的速度快的惊人
这篇文章写于学校实验课上,现在的我正在无奈于机房电脑上 pip 环境缓慢且不见跳动的下载进度条,当我掏出我自己的 Mac 并且采用 uv 进行构建时,下载速度问题神奇的消失了,在 uv 的魔法下,有关 Python 的一切都变得非常丝滑流畅。
在用 uv 的这近三个月里,我已经很久没有遇到之前 python 运行和依赖安装时缓慢的圈圈了。
这是官方在 Github 中给出的性能测试,我们可以看到他真的很快~
uv 的功能补足你对 Python 包管理的所有幻想
uv 为速度而来,为多功能而生
虽然很多人转向 uv 的理由是 more fast
,但是更多人沉迷在 uv 中的理由绝对是 more function
!
open Python by uv
你可以得到快捷的 Python 版本管理,兼容 pip 等包管理工具依赖管理,更现代的虚拟环境管理、更简洁的依赖管理与更愉悦的 run python
uv 的锈化带给未来更多的可能
uv 最具争议的一方面绝对是它是由一家风投支持公司创建所拥有的,这意味着在短期内,uv有着大量资源的支持,我们可以看到,uv 迄今为止的表现是,一群非常聪明的人在努力的 work,积极推动 uv、文档和整个生态系统更加出色。团队不断发布更新去解决 Github iusse,为 uv 倾斜大量精力和资源。
这一切造就了 uv 从最初功能并不多,体验除了 more fast 之外并不算好的工具,发展到今天能够接管你整个项目的工具。
每一个工具从零开始到接管你项目的构建,到最后为你的工程加速,我们可以说,uv 已经迈出了生死存亡的第一步。当然,我们不能保证某后的风投不会来收取他们的汇报。我们不能保证 uv 永远光明,但就目前而言,uv 的发展还是十分出色的。同时,由于 uv 采用 MIT 开源协议,为社区提供了一条紧急逃生通道可以接管,So let's end the discussion of why and move on to the discussion of how!
如何使用 uv
step 1 安装 uv
我们可以基于现有的 python 环境来安装 uv
bash
pip install uv -g
当然 MacOS 的生态下,我还是更喜欢 all in homebrew
bash
brew install uv
step 2 将 uv 融入现有工作流
使用 uv 安装 Python
bash
uv python install 3.11
这比通过标准渠道手动安装 Python 或者通过 homebrew 安装 Python 更加简单可靠。只需uv python install
。
使用 uv 管理虚拟环境
uv 提供了现有工具的直接替代品,因此我们不需要同以前一样通过 python -m venv
或者 conda env
来创建虚拟环境,而是通过uv venv /path/to/environment --python python-version
来直接替代,这样的好处是你再也不需要担心 Python 的安装问题。如果 uv 找不到正确的 Python 版本,他会自动下载并为你安装正确的版本。
uv 是如何管理虚拟环境的 在 Python 生态中,长期以来,关于虚拟环境具体应该放在哪里一直没有明确的最佳实践:
- 集中存放在某个目录下,e.g.
~/.virtualenvs
or/opt/virtualenves
- 放在项目中,e.g.
.venv
or.env
而在 uv 中,很明显项目内部获胜(感谢伟大的node_modules
),因为这样可以使 IDE 更容易得找到项目所需要的一切!
使用 uv 安装依赖
uv 为安装依赖提供了一个非常熟悉且开箱即用的接口,曾经我们习惯于pip install xxx
,而现在我们选择了uv pip install xxx
,那么这样做有什么好处呢?
很简单,more fast
使用 uv 管理依赖
大多数项目下,我们通常是将其依赖与 Python 相结合,Python 依赖项历史上被包含在诸如 requirements.txt
、setup.py
和 pyproject.toml
文件中,并由各种工具管理,如 pip-tools、Poetry、PDM、Pipenv 和 Conda。
除了有时帮助管理环境外,这些工具大多做的是帮助将一组基础 需求------项目直接使用的包------转换成一组完整 需求------那些其他包需要运行的包。它们还有助于将包固定到特定版本并解决包之间的依赖关系。
这些工具帮助我能够在只关心我所需要的依赖下,能够获取到正确其他所需依赖版本。
而使用 uv 我们也仅需要 uv pip compile requirements.in
,便可以兼容我们传统项目并且获得巨大的速度提升。
功能 | 传统工具 | 命令示例 | 使用 uv |
---|---|---|---|
安装 Python | homebrew, apt, deadsnakes, pyenv 等 | sudo apt install python3 |
uv python install |
创建虚拟环境 | venv, virtualenv | python -m venv .venv |
uv venv |
安装包 | pip | pip install django |
uv pip install django |
构建依赖 | pip-tools, poetry | pip-compile requirements.in -o requirements.txt |
uv pip compile requirements.in -o requirements.txt |
Step 3 采用 uv 作为新的工作流
我们在前面聚焦于 uv 是如何如何好、如何如何快,我们出发的视角一直是将 uv 作为我们已经在使用的特定工具的替代品。我们从中也可以感受到,uv 团队为了让我们利用 uv 的强大功能和速度,无缝衔接我们的工作流程,我们很难估量 uv 团队背后为此付出了多少心血。但是 uv 团队一定是深知采用新工具需要时间,而让人们接受新工具的最简单方法就是提供易于采用的解决方案。
而且 uv 自身的愿景是成为一个统治所有的终极工具。如果你足够勇敢去采用它,你可以更新几乎所有的工作流程------大多数情况下都会变得更好!
使用 uv 新建项目
bash
uv init yourproject
我们可以通过上述命令来开始一个崭新的 Python 项目
.
├── .gitignore
├── .python-version
├── README.md
├── README.md
├── hello.py
└── pyproject.toml
使用 uv 进行依赖管理
bash
uv sync
通过 uv 提供的原生方式,我们可以快速的构建依赖环境,在 uv sync
下,uv 将完成以下工作:
- 查找或下载适合使用的 Python 版本
- 在
.venv
文件夹中创建并设置环境 - 构建完整的依赖列表并写入
uv.lock
文件 - 将项目依赖同步到虚拟环境中
随后,我们可以通过 uv add
或者 uv remove
来新增与移除对应的依赖,在这一步中 uv 将完成以下几个工作:
- 更新 pyproject.toml 文件中的依赖项
- 更新 uv.lock 文件
- 同步你的环境
或者,你也可以直接编辑 pyproject.toml 文件,然后运行 uv lock
(仅更新锁文件)或 uv sync
(更新锁文件和环境)。
使用 uv 运行项目
你仅需要 uv run hello.py
即可运行你的项目。
在这一步中,我们完全不用担心同步或管理环境,因为 uv 会检查一切是否最新,修复任何问题,然后运行你的命令。
操作 | uv 命令 | 说明 |
---|---|---|
项目依赖文件 | pyproject.toml |
基础/核心依赖项在此文件中定义。 |
项目锁文件 | uv.lock |
派生依赖项在此通用锁文件中管理。 |
安装 Python | uv sync 或 uv run |
在同步或在环境中运行代码时,uv 会根据需要查找或安装 Python。 |
创建虚拟环境 | uv sync 或 uv run |
首次使用时,uv 会在需要时创建虚拟环境。 |
安装包 | uv sync 或 uv run |
每次使用时,uv 会将所需的所有包安装到环境中。 |
构建依赖项 | uv sync 或 uv run |
每次运行时,uv 都会从依赖项重新构建锁文件。 |
添加包 | uv add |
将包添加到 pyproject.toml、uv.lock 并同步环境。 |
移除包 | uv remove |
从 pyproject.toml、uv.lock 中移除包并同步环境。 |
升级包 | uv sync --upgrade-package <package> |
在 uv.lock 文件中升级包并同步环境。 |
升级所有包 | uv lock --upgrade |
根据 pyproject.toml 中的版本约束,升级 uv.lock 文件中的所有包。 |
使用 uv 满足不同环境下的需求
将需求分为常规、开发和生产需求是很常见的做法。在pip-tools世界中,这通常意味着为每组需求创建不同的requirements.in文件。
而 uv 中的依赖组,显然是专为此设计的。
在不同依赖组中添加、删除和更改包
你可以通过向uv add
传递--group
标志将包添加到依赖组中:
csharp
uv add fastapi --group production
这将在pyproject.toml文件中添加如下内容:
ini
[project.optional-dependencies]
production = ["fastapi"]
uv add
还支持--dev
标志,自动将依赖添加到dev组:
sql
uv add pytest --dev
这将更新文件如下:
ini
[project.optional-dependencies]
dev = ["pytest"]
关于使用 uv,在一开始习惯了 PyCharm,在刚使用 uv 时,由于 PyCharm 没有支持 uv 在使用起来还是比较别扭的,后面 Trae 发布后,借助 LLM 的能力,也是获得了十分丝滑的开发体验。
感谢 Trae 的出现,极大的减轻了我在学习使用 uv 时可能会遭受的痛苦~
"The dawn of LLM will surely illuminate a new era of software development"