所有文章

uv 使用指南 — 极速 Python 包与项目管理器

  • Python
  • uv
  • 包管理
  • 工具链
文章目录

uv 是由 Astral 公司(Ruff 的创造者)用 Rust 开发的下一代 Python 包和项目管理器。它不仅仅是 pip 的替代品,而是一个一体化的 Python 工具链,覆盖了从包安装、项目管理、Python 版本管理到脚本运行的完整工作流。

uv 的核心优势

  • ⚡ 极致速度 — 用 Rust 编写,缓存和并发安装设计,比 pip 快 10-100 倍
  • 📦 全能工具链 — 替代 pip、pip-tools、pipx、poetry、pyenv、virtualenv 等多个工具
  • 🔒 通用锁文件 — 支持跨平台的依赖锁定,确保环境一致性
  • 💾 磁盘高效 — 全局缓存去重,节省磁盘空间

💡 uv 不是又一个 Python 包管理器,而是一个完整的 Python 项目工具链。无论是简单脚本、完整项目还是 CLI 工具分发,uv 都提供了对应的命令。

安装方式

官方安装脚本(推荐)

macOS / Linux:

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

Windows (PowerShell):

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

其他安装方式

方式 命令 说明
pip pip install uv 通过现有 Python 环境安装
Homebrew brew install uv macOS / Linux
pipx pipx install uv 隔离安装
scoop scoop install uv Windows

验证安装

uv --version

💡 uv 安装不需要预先安装 Python 或 Rust,官方安装脚本会自动下载二进制文件。

核心概念:命令体系

uv 的命令按功能分为几大类:

分类 命令 用途 替代工具
项目管理 uv init / uv add / uv sync / uv lock 创建和管理 Python 项目 poetry / pdm
pip 兼容 uv pip install / uv pip compile / uv pip sync 类 pip 的依赖管理 pip / pip-tools
脚本运行 uv run 运行脚本或项目命令 (无需激活 venv)
工具管理 uv tool install / uvx 安装和运行 CLI 工具 pipx
Python 版本 uv python install / uv python pin 管理 Python 版本 pyenv
虚拟环境 uv venv 创建虚拟环境 virtualenv / venv

项目管理(uv init / add / sync / lock)

这是 uv 最核心也最推荐的使用方式,类似于 Poetry 或 PDM 的工作流。

初始化项目

# 创建新项目
uv init my-project
cd my-project

# 在当前目录初始化
uv init

初始化后会生成以下文件:

  • pyproject.toml — 项目配置和依赖声明
  • .venv/ — 虚拟环境目录(首次添加依赖时自动创建)
  • src/ — 源码目录(如果使用 --package

添加依赖

# 添加运行时依赖
uv add requests

# 添加开发依赖
uv add --dev pytest ruff

# 添加指定版本
uv add requests==2.31.0
uv add "requests>=2.31.0,<3"

# 从 Git 安装
uv add git+https://github.com/psf/requests.git

# 从本地路径安装
uv add ../my-local-package

同步与锁定

# 根据 lockfile 同步环境(安装所有依赖)
uv sync

# 仅同步生产依赖(不含 dev)
uv sync --no-dev

# 生成/更新 uv.lock 锁文件
uv lock

# 升级所有依赖到最新兼容版本
uv lock --upgrade

# 升级指定依赖
uv lock --upgrade-package requests

运行命令

# 在项目虚拟环境中运行命令
uv run python script.py
uv run pytest tests/
uv run ruff check src/

# 运行项目定义的脚本(在 pyproject.toml 中 [project.scripts])
uv run my-script

💡 无需手动激活 venv:使用 uv run 会自动在项目的虚拟环境中执行命令,不需要 source .venv/bin/activate

移除依赖

uv remove requests
uv remove --dev pytest

pyproject.toml 示例

[project]
name = "my-project"
version = "0.1.0"
description = "一个示例项目"
requires-python = ">=3.10"
dependencies = [
    "requests>=2.31.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0",
    "ruff>=0.4.0",
]

[tool.uv]
dev-dependencies = [
    "pytest>=7.0",
    "ruff>=0.4.0",
]

[project.scripts]
my-cli = "my_project.cli:main"

导出 requirements.txt

uv 提供了 uv export 命令,用于将项目依赖(从 pyproject.tomluv.lock)导出为标准的 requirements.txt 格式,方便与不使用 uv 的团队或工具(如 Docker、CI 系统)兼容。

基础导出

# 导出生产依赖(默认格式为 requirements.txt)
uv export > requirements.txt

# 显式指定格式
uv export --format requirements.txt > requirements.txt

# 导出包含开发依赖
uv export --dev > requirements-dev.txt

# 导出所有分组的依赖
uv export --all-groups > requirements-all.txt

常用导出选项

选项 说明 示例
--format <fmt> 导出格式,支持 requirements.txt(默认)和 pyproject.toml --format requirements.txt
--dev 包含开发依赖 uv export --dev
--all-groups 包含所有依赖分组的包 uv export --all-groups
--group <name> 包含指定分组的依赖(可多次指定) --group docs --group test
--no-dev 排除开发依赖 uv export --no-dev
--locked 从 lockfile 导出精确版本(无版本范围,保证完全一致),需要先执行 uv lock uv export --locked
--frozen 使用现有 lockfile,不更新 uv export --frozen
--no-hashes 不输出哈希校验值(输出更简洁) uv export --no-hashes
--no-annotate 不输出注释(每个包属于哪个分组的标注) uv export --no-annotate
--no-header 不输出文件头注释 uv export --no-header
--all-packages 导出所有包(包括工作区内的本地包) uv export --all-packages
--extras <name> 包含指定的 extras 可选依赖 --extras http2
--all-extras 包含所有 extras 可选依赖 uv export --all-extras
--output-file <path> 输出到指定文件(替代重定向) --output-file requirements.txt

常见使用场景

场景一:生产环境部署(仅生产依赖,精确版本)

# 从 lockfile 导出精确的生产依赖版本,用于部署
uv export --locked --no-dev --output-file requirements.txt

场景二:开发环境共享(含开发依赖,简洁格式)

# 导出包含 dev 依赖,去掉哈希和注释,方便阅读
uv export --dev --no-hashes --no-annotate > requirements-dev.txt

场景三:干净极简版(无哈希、无注释、无表头)

# 最干净的输出,类似 pip freeze 的效果
uv export --format requirements.txt --all-groups --no-hashes \
  --no-annotate --no-header > requirements.txt

场景四:CI / Docker 构建(严格锁定)

# 使用已有的 lockfile,不进行网络解析,确保 CI 环境可复现
uv export --frozen --locked --no-dev --output-file requirements.txt

场景五:导出指定分组

# 只导出 docs 和 test 分组的依赖
uv export --group docs --group test --no-hashes > requirements-test.txt

💡 uv export vs uv pip freezeuv exportpyproject.toml 声明的依赖出发(可结合 lockfile),输出的是声明的依赖及其传递依赖,支持分组、extras 等高级选项。uv pip freeze 则是直接输出当前虚拟环境中所有已安装的包,类似 pip freeze。推荐使用 uv export,因为它基于项目声明,更干净可靠。

使用 uv pip freeze(备选方案)

如果你更习惯 pip freeze 的方式,可以用以下命令导出当前虚拟环境中的所有包:

# 导出当前环境所有已安装包(类似 pip freeze)
uv pip freeze > requirements.txt

# 导出到指定虚拟环境
uv pip freeze --python .venv/bin/python > requirements.txt

pip 兼容接口(uv pip)

如果你习惯了 pip 的工作流,uv 提供了 uv pip 子命令作为 drop-in 替代,同时享受 10-100 倍的速度提升。

基本安装

# 安装包(类似于 pip install)
uv pip install requests

# 安装到指定虚拟环境
uv pip install --python .venv/bin/python requests

# 从 requirements.txt 安装
uv pip install -r requirements.txt

# 可编辑安装
uv pip install -e .

pip-tools 风格

uv pip 集成了 pip-tools 的 compile 和 sync 功能:

# 将 requirements.in 编译为锁定版本的 requirements.txt
uv pip compile requirements.in -o requirements.txt

# 生成跨平台通用锁文件
uv pip compile requirements.in --universal -o requirements.txt

# 完全同步环境(安装+卸载,与 requirements.txt 精确一致)
uv pip sync requirements.txt

常用命令对照

pip 命令 uv pip 命令 说明
pip install pkg uv pip install pkg 安装包
pip install -r req.txt uv pip install -r req.txt 从文件安装
pip uninstall pkg uv pip uninstall pkg 卸载包
pip list uv pip list 列出已安装包
pip freeze uv pip freeze 导出依赖
pip-compile uv pip compile 编译依赖文件
pip-sync uv pip sync 同步依赖

⚠️ uv pip 命令不是 pip 的简单包装,而是用 Rust 完全重写的实现。绝大多数 pip 功能都支持,但极少数边缘功能可能不同。

单文件脚本(uv run script)

uv 支持像 pipx 运行脚本一样,在隔离环境中运行单个 Python 文件,并支持内联依赖声明。

内联依赖声明

在脚本顶部的特殊注释中声明依赖:

# /// script
# requires-python = ">=3.10"
# dependencies = [
#     "requests>=2.31.0",
#     "rich>=13.0",
# ]
# ///

import requests
from rich.console import Console

console = Console()
resp = requests.get("https://api.github.com")
console.print(f"Status: {resp.status_code}")

运行脚本

# 直接运行(自动创建临时环境)
uv run script.py

# 添加依赖到脚本
uv add --script script.py httpx

# 移除依赖
uv remove --script script.py requests

💡 这个功能特别适合分享单个脚本文件——接收者只需 uv run script.py 即可自动安装依赖并运行,无需手动创建环境。

工具安装与运行(uv tool / uvx)

uv 可以像 pipx 一样,在隔离环境中安装和运行命令行工具。

安装工具

# 永久安装工具
uv tool install ruff
uv tool install black
uv tool install poetry

# 安装指定版本
uv tool install ruff==0.5.0

# 列出已安装的工具
uv tool list

# 卸载工具
uv tool uninstall ruff

临时运行(uvx)

uvxuv tool run 的别名,用于在临时环境中运行工具:

# 运行一次(不持久安装)
uvx pycowsay "hello world"
uvx httpie GET https://api.github.com

# 指定版本
uvx ruff@0.5.0 --version

Python 版本管理(uv python)

uv 内置了 Python 版本管理功能,可以替代 pyenv。

安装与管理 Python

# 安装指定版本
uv python install 3.12
uv python install 3.10 3.11 3.12

# 安装预发布版本
uv python install 3.13.0-rc.1

# 安装 PyPy
uv python install pypy3.10

# 列出已安装的 Python 版本
uv python list

# 列出可用的 Python 版本
uv python list --all-versions

# 卸载版本
uv python uninstall 3.10

项目固定 Python 版本

# 在当前目录固定 Python 版本(生成 .python-version)
uv python pin 3.11

# 查看当前使用的 Python
uv python find

指定 Python 版本运行

# 使用指定版本创建虚拟环境
uv venv --python 3.12

# 使用指定版本运行
uv run --python 3.11 python --version
uv run --python pypy@3.10 python --version

虚拟环境(uv venv)

uv 提供了超快速的虚拟环境创建,替代 python -m venvvirtualenv

创建虚拟环境

# 在当前目录创建 .venv
uv venv

# 指定路径
uv venv .venv-dev

# 指定 Python 版本
uv venv --python 3.12
uv venv --python 3.11.9

# 命名虚拟环境
uv venv --name myenv

激活

# macOS / Linux
source .venv/bin/activate

# Windows (PowerShell)
.venv\Scripts\Activate.ps1

💡 在使用 uv pipuv run 时,uv 会自动发现当前目录的 .venv,很多情况下不需要手动激活。

工作区(Workspaces)

uv 支持 Cargo 风格的工作区,用于管理多包 monorepo 项目。

配置工作区

在根目录的 pyproject.toml 中声明:

[tool.uv.workspace]
members = [
    "packages/*",
    "apps/*",
]

# 可选:排除某些目录
exclude = [
    "packages/legacy",
]

工作区命令

# 同步所有包
uv sync

# 在特定包中运行命令
uv run --package my-package pytest

# 添加工作区内依赖
uv add --package app-a ../packages/common
# 或在 pyproject.toml 中:
# dependencies = [
#     "common @ {workspace}",
# ]

常用命令速查表

项目管理

命令 说明
uv init 初始化新项目
uv add <pkg> 添加依赖
uv add --dev <pkg> 添加开发依赖
uv remove <pkg> 移除依赖
uv sync 同步环境
uv lock 生成锁文件
uv export 导出 requirements.txt
uv export --locked 导出精确版本(基于 lockfile)
uv export --dev 导出含开发依赖
uv run <cmd> 在 venv 中运行命令
uv build 构建包
uv publish 发布到 PyPI

Pip 兼容

命令 说明
uv pip install <pkg> 安装包
uv pip install -r req.txt 从文件安装
uv pip compile req.in 编译依赖
uv pip sync req.txt 同步依赖
uv pip uninstall <pkg> 卸载包
uv pip list 列出已安装包
uv pip freeze 导出依赖(当前环境所有包)

其他常用

命令 说明
uv venv 创建虚拟环境
uv python install 3.12 安装 Python 版本
uv python pin 3.11 固定项目 Python 版本
uv tool install ruff 安装全局工具
uvx <tool> 临时运行工具
uv cache clean 清理缓存
uv self update 更新 uv 自身

从 pip / poetry 迁移

从 pip + requirements.txt 迁移

# 方式一:使用 uv pip(最小改动)
uv pip install -r requirements.txt

# 方式二:迁移到 uv 项目管理
uv init
# 然后手动添加依赖
uv add $(cat requirements.txt | tr '\n' ' ')

从 Poetry 迁移

# uv 可以直接读取 pyproject.toml
# 如果 pyproject.toml 使用 PEP 621 格式([project] 表):
uv sync

# 如果是 poetry 格式([tool.poetry]),需要先转换格式
# 可以使用 uv migrate 或手动调整

💡 迁移建议:新项目推荐直接使用 uv 的项目管理模式(uv init + uv add + uv sync)。现有项目可以先用 uv pip 作为 drop-in 替换,享受速度提升,再逐步迁移到完整的项目管理模式。

最佳实践

  1. 新项目用 uv init — 新项目直接使用 uv 的项目管理模式,享受锁文件、依赖解析等完整功能
  2. 提交 uv.lock — 将 uv.lock 提交到版本控制,确保团队和 CI 环境的依赖一致
  3. 使用 .python-version — 用 uv python pin 固定 Python 版本,让项目自包含
  4. uv run 替代激活 — 用 uv run 运行命令,省去手动激活 venv 的步骤
  5. 定期清理缓存uv cache clean 清理旧缓存,释放磁盘空间
  6. CI/CD 中使用 uv — CI 环境中使用 uv pip sync 或 uv sync 大幅缩短依赖安装时间

参考来源