Why and How Should We Use uv? - Python Package and Project Management

Made by Mike_Zhang


Unfold Python Topics | 展开Python主题 $\triangledown$


Python环境管理并不可怕,可怕的是每次换一台机器都要重新配一遍环境。


NO BULLSHIT

30秒开门见山版

如果你只是想快速知道uv怎么用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create a new Python project
uv init my-project
cd my-project

# Add dependency
uv add requests
uv add "requests>=2.31,<3"

# Run Python file in the project environment
uv run main.py

# Sync environment from lockfile
uv sync

# Run a Python tool without installing it globally
uvx ruff check .

简单来说:

  • uv可以用来管理Python版本虚拟环境项目依赖命令行工具脚本依赖
  • 对新项目,优先使用uv init + uv add + uv run + uv sync
  • 对旧项目,可以先用uv venvuv pip install -r requirements.txt低成本迁移;
  • 如果项目已经有uv.lock,其他机器上通常只需要uv sync就能复现环境;
  • uv很快,但不是魔法。若项目强依赖Conda channel、复杂CUDA系统库,仍然需要结合具体情况判断。

Intro

导言

配置Python环境,常常是一个让人头疼的过程。

我们可能会遇到:

  • 这个项目用Python 3.10,另一个项目用Python 3.12
  • 一个项目用pip install -r requirements.txt,另一个项目用conda env create
  • 电脑里有很多个venvconda env,时间一长就不知道哪个环境对应哪个项目;
  • 在自己电脑上能跑,换到服务器、实验室电脑、同学电脑上就开始报错;
  • 安装依赖很慢,尤其是网络不稳定或者依赖很多时。

之前我写过Conda Environment Transfer,主要解决的是:如何把一个已经配置好的Conda环境迁移到另一台机器上

而这篇文章想介绍另一个思路:

与其到处搬环境,不如让项目本身清楚地记录环境和依赖,然后在需要的时候自动创建和同步。

这就是uv很适合解决的问题。


1. What is uv

1. uv是什么

uv是由Astral开发的Python package and project manager。官方介绍中将其描述为一个用Rust编写的高速Python包和项目管理工具。

官方文档中提到,uv的目标不是只替代某一个工具,而是覆盖很多常见Python开发工具的工作流,例如:

  • pip
  • pip-tools
  • pipx
  • poetry
  • pyenv
  • virtualenv
  • 等等

也就是说,uv不只是一个“更快的pip”,而是一个更完整的Python项目管理工具。

它大致可以处理下面几类事情:

Task Old Workflow uv Workflow
创建虚拟环境 python -m venv .venv uv venv
安装包 pip install requests uv add requests or uv pip install requests
运行项目 手动激活环境后运行 uv run main.py
锁定依赖 pip freeze > requirements.txt uv.lock
安装Python工具 pipx install ruff uv tool install ruff
临时运行工具 pipx run ruff uvx ruff
管理Python版本 pyenv install 3.12 uv python install 3.12
uv project workflow

2. Why Should We Use uv

2. 为什么使用uv

2.1 Faster

2.1 更快

官方文档称uv在一些场景下可以比pip10-100x

速度不是唯一原因,但确实是最直观的原因。对于依赖比较多的项目,比如机器学习、Web后端、数据分析项目,安装依赖的时间常常很长。如果可以减少等待时间,开发体验会好很多。

不过,我认为更重要的不是“快”,而是下面几点。


2.2 One Tool for Many Jobs

2.2 一个工具覆盖多个流程

以前我们可能需要同时记住:

1
2
3
4
5
6
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip freeze > requirements.txt
pipx run ruff
pyenv local 3.12

现在很多情况下可以变成:

1
2
3
4
5
uv init
uv add requests
uv run main.py
uv sync
uvx ruff check .

命令减少后,不仅是输入更少,更重要的是心智负担降低


2.3 Project Environment is Clearer

2.3 项目环境更清晰

uv项目通常会包含几个重要文件:

1
2
3
4
5
6
7
8
9
my-project/
├── .git/
├── .gitignore
├── .python-version
├── .venv/
├── README.md
├── main.py
├── pyproject.toml
└── uv.lock

其中:

  • .python-version记录项目默认使用的Python版本;
  • .venv是项目本地的虚拟环境;
  • pyproject.toml记录项目元信息和依赖;
  • uv.lock记录解析后的精确依赖版本;
  • uv.lock应该提交到版本控制中,以便在不同机器上复现一致环境。

这就让Python项目更像一个完整的工程,而不是一个散落着很多依赖说明文件的文件夹。


2.4 Reproducible

2.4 更容易复现

如果项目里只有一个requirements.txt,通常能记录直接依赖和版本,但面对不同平台、不同Python版本、间接依赖时,仍然可能出现差异。

uv.lockuv生成的lockfile,用来记录项目依赖解析后的结果。官方文档说明,uv.lock是跨平台的lockfile,用来帮助不同开发者和不同机器保持一致的依赖版本。

这对于科研代码、课程项目、长期维护的工具尤其重要。

我个人理解是:

pyproject.toml告诉别人“这个项目大概需要什么”,uv.lock告诉别人“这一次实际解析出来的环境是什么”。


3. Installation

3. 安装

官方文档首先列出的安装方式是使用standalone installer。

3.1 macOS / Linux

1
curl -LsSf https://astral.sh/uv/install.sh | sh

如果没有curl,也可以使用wget

1
wget -qO- https://astral.sh/uv/install.sh | sh

安装完成后,重启终端,或者根据终端提示更新PATH

验证安装:

1
uv --version

3.2 Homebrew

如果你使用macOS和Homebrew:

1
brew install uv

3.3 pipx / pip

官方文档也列出了PyPI安装方式。更推荐安装到隔离环境:

1
pipx install uv

也可以用:

1
pip install uv

不过,如果你已经决定用uv来减少Python环境混乱,我更推荐使用standalone installer或者Homebrew,而不是把uv安装在某个可能会被删除的Python环境里。


4. Basic Project Workflow

4. 基本项目流程

4.1 Create a New Project

4.1 创建新项目

1
2
uv init hello-uv
cd hello-uv

这会创建一个基本的Python项目。官方文档中说明,uv init会创建如pyproject.toml.python-versionREADME.mdmain.py等文件。

运行项目:

1
uv run main.py

这里不需要手动source .venv/bin/activateuv run会在项目环境中运行命令,并确保环境与项目依赖保持同步。


4.2 Add Dependencies

4.2 添加依赖

例如我们想使用requests

1
uv add requests

这条命令会做几件事情:

  • requests加入pyproject.toml
  • 更新uv.lock
  • 同步项目虚拟环境。

如果需要指定版本,也可以直接写版本约束:

1
2
3
4
5
# Exact version
uv add "requests==2.31.0"

# Version range
uv add "requests>=2.31,<3"

官方文档中给出的例子包括uv add "httpx>=0.20",也说明依赖项可以写成类似torch ==2.2.2tqdm >=4.66.2,<5的形式。这里建议用引号包起来,避免><等符号被shell错误解释。

如果需要开发依赖,例如pytest

1
uv add --dev pytest

官方文档说明,开发依赖会进入dependency-groups,例如dev group。这样可以把运行项目需要的依赖和开发测试需要的依赖分开。


4.3 Run Code

4.3 运行代码

创建一个简单例子:

1
2
3
4
import requests

response = requests.get("https://httpbin.org/get")
print(response.status_code)

运行:

1
uv run main.py

如果项目有命令行工具,例如pytest

1
uv run pytest

4.4 Sync Environment

4.4 同步环境

当你换到另一台机器,或者重新clone项目后:

1
uv sync

uv sync会根据uv.lock同步项目环境。官方文档说明,uv sync默认会进行exact sync,也就是移除lockfile中不存在的多余包。

这点很重要,因为它避免了“这个包不知道什么时候被我手动装进去了,但其实项目并不需要”的情况。


5. Existing Project Workflow

5. 已有项目如何迁移

如果你已经有一个普通Python项目,例如:

1
2
3
old-project/
├── main.py
└── requirements.txt

可以先进入项目:

1
cd old-project

初始化uv项目:

1
uv init

requirements.txt导入依赖:

1
uv add -r requirements.txt

运行:

1
uv run main.py

如果你不想立刻迁移到pyproject.tomluv.lock的完整项目管理方式,也可以先使用uv pip接口。


6. uv pip Interface

6. uv pip接口

uv提供了类似pippip-toolsvirtualenv的接口。官方文档特别说明,uv pip并不是调用pip,而是uv自己实现的pip-style interface。

创建虚拟环境:

1
uv venv

指定Python版本:

1
uv venv --python 3.12

安装依赖:

1
uv pip install flask

指定版本或版本范围:

1
2
uv pip install "ruff==0.3.0"
uv pip install "ruff>=0.2.0"

requirements.txt安装:

1
uv pip install -r requirements.txt

查看当前环境包:

1
2
uv pip list
uv pip freeze

官方文档中也提醒,uv pip虽然提供了熟悉的接口,但并不在所有边缘行为上与pip完全一致。因此,如果是复杂项目迁移,最好先在测试环境验证。


7. Scripts

7. 单文件脚本

有时我们只是想运行一个小脚本,并不想为了它创建一个完整项目。

例如:

1
2
3
4
5
from rich.progress import track
import time

for i in track(range(20), description="Processing"):
time.sleep(0.05)

如果本机没有安装rich,普通运行会报错。使用uv可以临时带上依赖:

1
uv run --with rich script.py

也可以给脚本添加inline metadata:

1
2
3
uv init --script example.py --python 3.12
uv add --script example.py requests rich
uv run example.py

这个功能很适合:

  • 小型数据处理脚本;
  • 临时实验脚本;
  • 分享给别人运行的单文件demo;
  • 不想污染全局环境的脚本。

8. Tools

8. Python命令行工具

以前我们可能会用pipx安装Python命令行工具。uv也提供了类似功能。

临时运行工具:

1
uvx ruff check .

uvxuv tool run的别名,适合临时运行某个工具。

长期安装工具:

1
2
uv tool install ruff
ruff --version

我比较推荐:

  • 偶尔用一次:uvx
  • 经常使用:uv tool install
  • 项目内部工具:uv add --dev后用uv run
uv command cheat sheet

9. When Should We Use uv

9. 什么时候适合使用uv

我认为,下面这些场景非常适合:

  1. 新Python项目

直接从uv init开始,把项目依赖、Python版本、lockfile都整理好。

  1. 课程项目 / 科研代码 / 复现实验

pyproject.tomluv.lock提交到Git,换机器后用uv sync复现环境。

  1. 需要频繁创建环境的开发

相比手动创建venv、激活、安装依赖,uv runuv sync会更顺手。

  1. 小脚本

uv run --with和inline script metadata可以减少“为了一个脚本创建一个环境”的麻烦。

  1. Python命令行工具

uvxuv tool install可以减少全局Python环境污染。


10. When Should We Be Careful

10. 什么时候需要谨慎

uv很好用,但不代表所有情况都应该立刻迁移。

下面几类情况需要谨慎:

  • 项目已经有稳定的Conda环境和团队流程;
  • 项目强依赖Conda channel中的非Python依赖;
  • 项目涉及复杂CUDA、系统库、编译工具链;
  • 服务器或实验室平台已经规定了环境管理方式;
  • 老项目依赖关系混乱,直接迁移可能暴露很多历史问题。

我的建议是:

新项目优先尝试uv;旧项目先用uv pip低成本体验,再决定是否完整迁移。


11. Common Commands

11. 常用命令

11.1 Installation

1
2
3
4
curl -LsSf https://astral.sh/uv/install.sh | sh
brew install uv
pipx install uv
uv --version

11.2 Project

1
2
3
4
5
6
7
8
9
uv init my-project
uv add requests
uv add "requests==2.31.0"
uv add "requests>=2.31,<3"
uv add --dev pytest
uv remove requests
uv run main.py
uv sync
uv lock

11.3 pip-style

1
2
3
4
5
6
7
8
uv venv
uv venv --python 3.12
uv pip install flask
uv pip install "ruff==0.3.0"
uv pip install "ruff>=0.2.0"
uv pip install -r requirements.txt
uv pip list
uv pip freeze

11.4 Script and Tool

1
2
3
4
5
uv run --with rich script.py
uv init --script example.py --python 3.12
uv add --script example.py requests
uvx ruff check .
uv tool install ruff

12. Summary

12. 总结

uv最吸引我的地方,不只是快。

更重要的是,它把Python开发中很多分散的事情放到了一套相对统一的流程中:

  • Python版本;
  • 虚拟环境;
  • 项目依赖;
  • lockfile;
  • 单文件脚本;
  • 命令行工具。

如果用一句话总结:

uv让Python项目更像一个可以被清楚描述、快速同步、稳定复现的工程。

对我来说,如果以后要创建新的Python项目,我会优先考虑:

1
2
3
4
uv init
uv add ...
uv run ...
uv sync

这套流程足够简单,也足够现代。


References

Astral. uv Documentation - Introduction. https://docs.astral.sh/uv/ (accessed May 10, 2026).

Astral. uv Documentation - Installation. https://docs.astral.sh/uv/getting-started/installation/ (accessed May 10, 2026).

Astral. uv Documentation - Working on projects. https://docs.astral.sh/uv/guides/projects/ (accessed May 10, 2026).

Astral. uv Documentation - Managing dependencies. https://docs.astral.sh/uv/concepts/projects/dependencies/ (accessed May 10, 2026).

Astral. uv Documentation - Locking and syncing. https://docs.astral.sh/uv/concepts/projects/sync/ (accessed May 10, 2026).

Astral. uv Documentation - The pip interface. https://docs.astral.sh/uv/pip/ (accessed May 10, 2026).

Astral. uv Documentation - Managing packages with uv pip. https://docs.astral.sh/uv/pip/packages/ (accessed May 10, 2026).

Astral. uv Documentation - Running scripts. https://docs.astral.sh/uv/guides/scripts/ (accessed May 10, 2026).

Astral. uv Documentation - Using tools. https://docs.astral.sh/uv/guides/tools/ (accessed May 10, 2026).

Astral. uv Documentation - Installing and managing Python. https://docs.astral.sh/uv/guides/install-python/ (accessed May 10, 2026).


原创文章,转载请标明出处
Made by Mike_Zhang




感谢你的支持 | Thank you for supporting

Why and How Should We Use uv? - Python Package and Project Management
https://ultrafish.io/post/why-and-how-to-use-uv/
Author
Mike_Zhang
Posted on
May 10, 2026
Licensed under