0. 问题引入
用 Python 开发项目,一定经历过这些烦恼:
- 装包太慢,
pip install一等好几分钟 - 不同项目依赖冲突,环境一团乱麻
- 电脑上装了好几个 Python 版本,不知道用哪个
venv、pip、pyenv、pipx......工具太多,记不住
uv 的出现,正是为了解决这些问题。
1. uv 是什么?
uv 是由 Astral 公司(同时也是代码检查工具 ruff 的开发团队)推出的 Python 全能工具链,用 Rust 语言编写。
一句话概括:
uv 是一个极速的 Python 包管理器和项目管理工具,能替代 pip、venv、pyenv、pipx 等一系列工具。
2. 为什么需要 uv?
2.1 传统 Python 工具链的问题
长期以来,Python 开发者需要组合使用多个工具才能完成完整的开发工作:
管理 Python 版本 → pyenv
创建隔离环境 → venv / virtualenv
安装依赖包 → pip
锁定依赖版本 → pip-tools / poetry
安装命令行工具 → pipx
每个工具各司其职,但组合使用时学习成本高、配置繁琐,工具之间还可能出现兼容问题。
2.2 uv 的解决方式
uv 把上面所有工具的功能整合到一个命令中:
管理 Python 版本 ┐
创建隔离环境 │
安装依赖包 ├→ 统统交给 uv
锁定依赖版本 │
安装命令行工具 ┘
3. uv 的核心能力
3.1. 极速安装包
这是 uv 最直观的优势。同样安装一批依赖,uv 比 pip 快 10~100 倍。
bash
# 传统方式(慢)
pip install requests numpy pandas
# uv 方式(极快)
uv add requests numpy pandas
速度差异的根本原因:uv 用 Rust 编写,并行下载,智能缓存,而 pip 是纯 Python 实现。
3.2. 虚拟环境管理
uv 完全兼容 Python 标准的虚拟环境(venv),可以无缝替代。
bash
# 传统方式
python -m venv .venv
source .venv/bin/activate
# uv 方式
# uv 底层创建虚拟环境时,本质上和 venv 是兼容的
# uv 创建的环境,venv/pip 也能识别和使用
uv venv # 创建虚拟环境,等价于 python -m venv .venv
uv venv .venv # 指定目录名
关键点:uv 创建的虚拟环境和 venv 完全兼容,目录结构一模一样,pip 也能识别和使用。
**【uv vs venv】**工具层面对比:
bash
venv → 只是一个"创建隔离环境"的工具
uv → 是一个"全能工具链",包含了 venv 的功能,但远不止于此
类比:venv 是一把锤子,uv 是一个工具箱(里面包含锤子)
┌─────────────────────────────────────────┐
│ uv │ ← 全能工具链
│ ┌─────────┐ ┌──────┐ ┌───────────┐ │
│ │ Python │ │ venv │ │ pip │ │
│ │ 版本管理 │ │ 环境 │ │ 包管理 │ │
│ └─────────┘ └──────┘ └───────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ 项目管理 / 全局工具安装 │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
venv → 只对应中间那一个小方块
**【uv vs venv】**使用对比:
bash
#1. 传统方式(venv + pip),先得有 Python
python -m venv .venv # 创建环境
source .venv/bin/activate # 激活环境
pip install requests # 装包(慢)
pip freeze > requirements.txt # 手动锁版本
#2.uv 方式:
uv init # 初始化项目
uv add requests # 装包(极快,自动锁版本)
# 不需要手动激活环境,uv 自动处理
**【uv vs venv】**核心区别总结:
bash
venv:
- Python 标准库自带
- 只解决"环境隔离"一个问题
- 需要配合 pip 才能完整工作
uv:
- 第三方工具,需要单独安装
- 解决 Python 开发全链路问题
- 内置环境隔离 + 包管理 + 版本管理
- 速度极快(Rust 实现)
- 更现代的工作流
3.3. Python 版本管理
不需要额外安装 pyenv,uv 可以直接管理多个 Python 版本。
bash
uv python install 3.11 # 安装 Python 3.11
uv python install 3.12 # 安装 Python 3.12
uv python list # 查看已安装的版本
uv python pin 3.11 # 指定当前项目使用 3.11
甚至在你电脑上没有 Python 的情况下,uv 也能自动下载安装所需版本。
3.4. 项目管理与依赖锁定
uv 支持现代化的项目管理工作流,自动维护 pyproject.toml 和 uv.lock 文件。
bash
uv init myproject # 初始化新项目
cd myproject
uv add requests # 添加依赖(自动写入配置文件)
uv add pytest --dev # 添加开发依赖
uv sync # 根据锁文件同步环境(团队协作利器)
uv.lock 文件精确记录每个包的版本,保证团队所有人的环境完全一致。
pyproject.toml 和 uv.lock 是用来解决"环境一致性"问题的。
bash
【场景】假设你写了一个 Python 项目,发给同事运行,结果报错了。
排查发现:你用的是 requests 2.31,同事装的是 requests 2.28,行为不一致。
【核心问题】:如何让所有人用完全一样的环境?
pyproject.toml 和 uv.lock 就是解决这个问题的。
pyproject.toml 是【项目的"身份证"】,是Python 官方标准(PEP 517/518)定义的项目配置文件,描述这个项目"是什么"以及"需要什么"。
pyproject.toml结构如下:
bash
[project]
name = "myapp" # 项目名
version = "0.1.0" # 版本号
description = "我的应用"
requires-python = ">=3.11" # 需要的 Python 版本
# 项目依赖(核心部分)
dependencies = [
"requests>=2.28", # 需要 requests,版本 2.28 以上就行
"fastapi>=0.100",
"numpy", # 不限版本
]
[tool.uv]
dev-dependencies = [
"pytest>=7.0", # 开发时才需要的依赖
"black",
]
关键特点:写的是"范围",不是精确版本
bash
"requests>=2.28" # 2.28 或更高版本都可以
"fastapi>=0.100" # 0.100 或更高版本都可以
这是故意的------给版本留一定弹性,方便和其他包兼容。
类比理解:
bash
pyproject.toml ≈ 招聘要求
"需要有3年以上经验,会Python"
(描述条件,不指定具体某个人)
uv.lock 是【环境的"精确快照"】 ,是uv 自动生成的依赖锁定文件,精确记录实际安装的每一个包的确切版本。uv.lock结构如下:
bash
# 这个文件由 uv 自动生成,不要手动修改!
[[package]]
name = "requests"
version = "2.31.0" # 精确到具体版本
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "charset-normalizer" },
{ name = "idna" },
{ name = "urllib3" },
]
[[package]]
name = "certifi"
version = "2024.2.2" # requests 依赖的包,也锁定了
[[package]]
name = "charset-normalizer"
version = "3.3.2"
# ... 以下记录所有包,包括依赖的依赖
关键特点:记录所有包的精确版本,包括间接依赖
bash
你声明需要:requests
requests 依赖:certifi、urllib3、charset-normalizer、idna
这些包又各自有依赖...
uv.lock 把这整棵依赖树上的每一个包都锁死
类比理解:
bash
uv.lock ≈ 录用通知书
"张三,男,28岁,北京大学2018届..."
(记录具体某个人的精确信息)
两个文件的关系:
bash
pyproject.toml uv.lock
(你写的需求) (uv 生成的精确解)
│ │
│ uv 计算依赖关系 │
└──────────────────────→┘
"我需要 requests>=2.28" → "实际装的是 requests 2.31.0
以及它依赖的 certifi 2024.2.2
以及 urllib3 2.2.1
以及..."
工作流程:
bash
第一次运行 uv add requests
│
▼
uv 查找满足条件的最新版本
│
▼
更新 pyproject.toml ←─── 你可以看到和修改
更新 uv.lock ←─── uv 自动维护,不要手动改
│
▼
其他人运行 uv sync
│
▼
uv 读取 uv.lock,装完全一样的版本
同时需要pyproject.toml 和 uv.lock两个文件,因为他们服务目的不同:
bash
只有 pyproject.toml 会怎样?
─────────────────────────────
今天运行:装了 requests 2.31 ✅
一个月后:requests 发布了 2.32
同事运行:装了 requests 2.32 ← 版本不一样!可能有 bug!
只有 uv.lock 会怎样?
─────────────────────────────
太死板,无法表达"2.28以上都可以"的弹性需求
发布到 PyPI 供别人使用时,不能强制要求别人用同一个版本
两个都有:
─────────────────────────────
pyproject.toml → "这个项目需要什么",人写的,有弹性;表达灵活的版本需求(给人看的)
uv.lock → "实际装了什么",uv写的,很精确;锁定精确版本(给机器用的)
两者配合 → 既灵活又可复现,团队环境永远一致
实际场景理解
bash
---------------------------------------------
场景一:团队协作
---------------------------------------------
# 小明添加了一个新依赖
uv add pandas
# pyproject.toml 和 uv.lock 都自动更新
# 提交到 git
git add pyproject.toml uv.lock
git commit -m "添加 pandas 依赖"
# 小红拉取代码后
uv sync
# uv 读取 uv.lock,装完全一样的 pandas 版本
# 小红和小明的环境现在完全一致 ✅
---------------------------------------------
场景二:部署上线
---------------------------------------------
# 服务器上
uv sync --no-dev # 只装生产依赖,跳过开发工具
# 版本和开发环境完全一致,不会出现"本地好好的,线上出问题"
---------------------------------------------
场景三:升级依赖
---------------------------------------------
# 想升级所有包到最新版
uv lock --upgrade
# 只升级某个包
uv lock --upgrade-package requests
# uv.lock 更新了,但 pyproject.toml 的范围声明不变
3.5. 全局命令行工具安装
这个功能对应的是 pipx 的职责------把 Python 写的 CLI 工具安装为全局命令,同时不污染任何项目环境。
bash
uv tool install ruff # 安装代码检查工具
uv tool install black # 安装代码格式化工具
uv tool install httpie # 安装 HTTP 命令行工具
# 安装后可以直接在终端全局使用
ruff check .
black .
每个工具都运行在独立的隔离环境中,互不干扰。
4. uv 与传统工具的对比
| 功能 | 传统工具 | uv |
|---|---|---|
| 安装依赖 | pip | ✅ uv add |
| 创建虚拟环境 | venv | ✅ uv venv |
| 管理 Python 版本 | pyenv | ✅ uv python |
| 锁定依赖版本 | pip-tools | ✅ 自动生成 uv.lock |
| 安装全局工具 | pipx | ✅ uv tool install |
| 速度 | 普通 | ✅ 极快(Rust 实现) |
5. 实际工作流演示
5.1. 开始一个新项目
bash
# 1. 初始化项目
uv init myapp
cd myapp
# 2. 添加依赖
uv add fastapi uvicorn
# 3. 运行项目
uv run python main.py
5.2 接手他人项目
bash
# 1. 克隆代码
git clone https://github.com/xxx/project
cd project
# 2. 一键同步环境(自动安装正确的 Python 版本和所有依赖)
uv sync
# 3. 运行
uv run python main.py
传统方式需要手动对齐 Python 版本、手动创建虚拟环境、手动 pip install,uv 把这些全部压缩成一条命令。
6. 安装 uv
bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# 也可以用 pip 安装
pip install uv
安装完成后验证:
bash
uv --version
7. 总结
uv 并不是要颠覆 Python 生态,它底层完全兼容现有标准(pyproject.toml、标准虚拟环境格式、PyPI 包源),过去积累的知识都不会浪费。
它做的事情很简单:把原本分散的工具整合在一起,然后让一切变得更快。
| 过去 | 现在(uv) | |
|---|---|---|
| 工具数量 | 5~6 个 | 1 个 |
| 安装速度 | 慢 | 极快 |
| 环境一致性 | 需手动维护 | 自动锁定 |
| Python 版本 | 需单独管理 | 内置支持 |
| 学习成本 | 高 | 低 |