「TF」01 uv - “下一代Python包管理器”

Greetings!

嗨!这里是阿乎的博客!(> ▽ <) /~

今天我们来介绍一下uv,这个被称为“下一代Python包管理器”的工具。

1. What is uv?

根据官网的介绍,uv是"An extremely fast Python package and project manager, written in Rust.",即“一个用Rust编写的极快的Python包和项目管理器”。

Rust是一个近年来兴起的新一代系统编程语言,以强调“内存安全+高性能”的而著称。
自 Linux 6.1(2022年12月)起,Rust 被首次合并进主线内核,用于处理实验性代码和驱动。尽管目前代码比例很小,但它确实是 Linux 内核迈向“下一代 C 系列”语言方向的一大步。

下图是官网介绍的uv的亮点:
Highlights of uv

2. Why uv?

至少对我来说,uv实在是非常让人惊艳!

2.1. Speed

我认识Rust比认识uv要早。当时Rust一直饱受争议——一个被很多人鼓吹很强的语言却并没有很多实际应用,即便是部分放入Linux内核的行为也并非能让人信服。

然而,uv的出现却让我真正认识到Rust的强大。
Installing Trio's dependencies with a warm cache

Installing Trio’s dependencies with a warm cache

上图是uv在安装Trio库时的速度对比。可以看到,uv的速度远超其他传统工具!按官方的说法,“10-100x faster than pip”(比pip快10-100倍)!

2.2. All in one

uv的另一个亮点是它的“全能”,一个工具替代一堆工具(参考 GitHub:https://github.com/astral-sh/uv):

  • pipuv pip install ...

  • virtualenv:创建 .venv 等当前目录下的虚拟环境(uv venv

  • pip-tools:生成 .lock 文件并确保依赖一致性(uv lock, uv sync

  • poetry / pdm:项目初始化、添加/移除依赖、运行脚本和工具等

  • pipx:用 uv tooluvx 快速执行 CLI 工具(如 ruff、black

3. How to play with uv?

具体的使用方法可以参考官网的文档,但我会简单介绍一下基本用法。

3.1. Install uv

安装uv有两种主要方法:

  • 使用pip安装
    • pip install uv
  • 系统级安装
    • Windows:
      powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
    • MacOS and Linux:
      curl -sSfL https://astral.sh/uv/install.sh | sh

⚠️注意:由于信息时效性,以上命令不一定长期有效。
建议参考官网的安装说明获取最新的安装方法。

卸载详见官网的卸载说明

3.2. Update uv

更新uv非常简单,只需运行以下命令:

  • 如果是使用pip安装的:
    pip install --upgrade uv
  • 如果是系统级安装的:
    uv self update

3.3. uv and virtual environments

uv的对于Python的管理

Conda不同,uv是“枪弹分离”式地管理Python可执行文件和包依赖的。

Conda的每个虚拟环境都是一个独立的封闭空间,包含:

  • 独立的一套 Python 可执行文件(如Windows上的python.exe
  • 所有依赖库(包括 Python 和非 Python 包)

uv 的管理方式则是“分层”结构:

  • Python 各版本只需 全局缓存一份(~/.cache/uv/pythons
  • 每个项目只在 .venv 中保存当前项目需要的依赖(库文件),
  • Python 是从全局引用(软链接/绑定),而不是复制一份

这种特别的方式有效地减少了磁盘空间的占用!让我这样有“磁盘洁癖”的人感到非常舒适!

创建虚拟环境

你只需要在你的项目目录下运行以下命令即可创建一个虚拟环境:

uv venv # 在当前目录下的.venv创建一个虚拟环境(没有名字)
uv venv myenv # 在当前目录下的myenv创建一个叫做myenv的虚拟环境(位置为./myenv)
uv venv --python 3.11 # 指定Python版本创建虚拟环境(默认使用全局最新版本)

举个例子,以下代码会在当前目录下创建一个名为tmp_env的虚拟环境,并使用Python 3.11版本:

uv venv tmp_env --python 3.11

注意:如果指定的版本并没有安装,uv会自动下载并安装对应版本的Python。

激活&退出虚拟环境

  1. 如果使用的是默认的.venv目录(通过uv venv命令创建),那么之后的任意uv命令都会自动激活这个虚拟环境。
  2. 还有一种通用方法,即使用创建虚拟环境时自动生成的激活脚本<env_name>/Scripts/activate
  • 举个例子,在Windows上,你可以运行以下命令来激活名为tmp_env的虚拟环境:
.\tmp_env\Scripts\activate
  • 在Linux或MacOS上,你可以运行以下命令:
./tmp_env/bin/activate

退出虚拟环境倒是比较方便,无论是哪一个系统,你只需运行以下命令即可:

deactivate

3.4. Install packages

在说明如何安装包之前,我们必须得了解一个东西:pyproject.toml

它是 Python 官方(PEP 518)定义的项目配置文件,类似于:

  • JavaScript 项目的 package.json
  • Rust 的 Cargo.toml
  • 或者 Conda 的 environment.yml

pyproject.toml 文件包含了项目的元数据(如项目名称、版本、作者等。是的,项目其实是应该有名称的!)、依赖关系和构建配置等信息。

与虚拟环境的概念不同,它是项目级别的配置文件。(当然,它也会用于管理虚拟环境的依赖,即该文件中的dependencies字段)

通过uv有两种方法来安装包:

  1. pip法:(不推荐)
    uv pip install <package_name>
    这种方式类似于传统的pip,但它并不会写入pyproject.toml文件。
  2. uv add法:(推荐)
    uv add <package_name>
    这种方式会自动将包添加到pyproject.toml文件中,并且会处理依赖关系。

同时,当使用uv add法安装包时,uv还会更新一个名为uv.lock的文件,这个文件类似于npmpackage-lock.json,用于锁定依赖版本,记录了项目所有依赖的精确版本(包括递归依赖)。

uv sync命令会根据uv.lock文件将 .venv 环境中的安装状态完全调整成 lockfile 中记录的内容。

3.5. Summary

简单总结一下uv的基本用法:

  • 创建虚拟环境:uv venvuv venv <env_name>,可以用--python指定Python版本。
  • 激活虚拟环境:通过<env_name>/Scripts/activate的脚本
  • 退出虚拟环境:deactivate
  • 安装包:
    • 使用uv pip install <package_name>(不推荐)
    • 使用uv add <package_name>(推荐)

4. Use uv in your projects

4.1. Initialize a project

实际上,我们还有一个uv init命令可以用来初始化一个新的项目,这个命令会自动创建pyproject.toml等关键文件,让你的新项目更加规范。

uv init my_project

这个命令会在当前目录下创建一个名为my_project的目录,并在其中生成所有项目基本文件:

my_project/
├── .gitignore # git 忽略文件
├── .python-version # 记录 Python 版本的文件,以明文记录该项目使用的 Python 版本
├── main.py # 主程序文件
├── pyproject.toml # 项目配置文件
└── README.md # 项目说明文件

此时,初始化并未完成!

接下来我们可以使用uv run main.py来运行项目的主程序。
在此之后项目的目录结构会变成这样:

my_project/
├── .venv # 虚拟环境目录
├── .gitignore
├── .python-version
├── main.py
├── pyproject.toml
├── README.md
└── uv.lock # 锁定依赖版本的文件

也就是说:在第一次通过uv运行项目后,uv会自动创建一个虚拟环境,并将其与项目关联起来。

4.2. Add dependencies

之后我们就可以使用uv add <package_name>来安装项目所需的依赖包了。

现在,检查一下你的pyproject.toml文件和uv.lock文件。或许可以考虑截图便于之后对比。

让我们以rich库为例

uv add rich

之后可以观察到:

  1. pyproject.toml 文件中会自动添加 richdependencies 字段中
  2. uv.lock 文件中会记录 rich 的具体版本和依赖关系(会有很多递归依赖,比如说rich 依赖于 pygmentsmdurl 等等)
  3. .venv 目录中会安装 rich 及其所有依赖

让我们修改一下main.py 文件,添加一些使用 rich 的代码:

from rich import print

def main():
    print("Hello, uv!") # 不使用 rich 美化输出
    print("[bold green]Hello, uv![/bold green]")  # 使用 rich 美化输出

if __name__ == "__main__":
    main()

之后再运行这个项目:

uv run main.py

那么你就可以看到两种颜色的输出了:
Output with rich

5. 结语

我在写这篇文章的时候,还并没有很多的uv使用经验(毕竟condapip已经用三四年了,没有第一时间尝试uv),但我意识到越来越多的项目开始使用uv作为包管理器。因此第一时间写下这篇文章,分享给大家。

希望能帮到大家!

Have fun! 😉

Reference

uv官网: https://docs.astral.sh/uv/


「TF」01 uv - “下一代Python包管理器”
https://siriusahu.github.io.git/2025/06/17/TF-01-UV/
Author
Sirius Ahu
Posted on
June 17, 2025
Licensed under