Python 开发者的新神器uv 全面指南如果你是一名 Python 开发者那么你大概率经历过这样的场景pipinstallxxx然后……等。安装几个依赖还好如果项目依赖比较复杂可能还会遇到依赖冲突 版本不一致 虚拟环境混乱 requirements.txt 不准确 不同电脑安装结果不同 Python 版本管理麻烦于是 Python 社区出现了很多工具pip安装 Python 包venv创建虚拟环境pip-tools锁定依赖virtualenv虚拟环境管理Poetry项目和依赖管理pyenvPython 版本管理pipx管理 Python CLI 工具每个工具都解决一个问题。但问题也来了为什么 Python 项目环境管理不能像 Rust 的 Cargo 一样一个工具全部搞定这正是uv想解决的问题。一、uv 到底是什么uv 是由Astral开发的 Python 包管理和项目管理工具。Astral 也是著名 Python 工具Ruff的开发团队。uv 使用Rust编写最初定位是一个非常高速的 Python package installer 和 resolver也就是高速安装 Python 包 高速解析 Python 依赖。uv 在 2024 年 2 月正式发布最开始主要被定位为pip和pip-tools的高速替代品。官方早期测试中uv 在无缓存场景下相比 pip/pip-tools 可以达到约 810 倍速度而在暖缓存场景下曾达到约 80115 倍的速度。(Astral)当然实际速度会受到网络CPU磁盘Python 包类型是否命中缓存操作系统等因素影响。所以网上经常看到的“uv 比 pip 快 100 倍”更准确地说应该理解成在特定依赖安装和缓存场景下uv 可以比传统 Python 工具快很多而不是任何情况下都固定快 100 倍。二、uv 为什么会出现要理解 uv首先要理解 Python 原来的工具链。传统 Python 项目经常是这样的Python │ ├── pip │ └── 安装依赖 │ ├── venv │ └── 创建虚拟环境 │ ├── requirements.txt │ └── 保存依赖 │ ├── pip-tools │ └── 锁定依赖 │ ├── pyenv │ └── 管理 Python 版本 │ └── pipx └── 管理 CLI 工具这套体系当然可以工作。但是对于现代 Python 项目来说开发者需要在不同工具之间来回切换。例如python-mvenv .venvsource.venv/bin/activate pipinstallrequests pip freezerequirements.txtWindows 还需要.venv\Scripts\activate如果需要换 Python 版本又需要另外解决。如果需要安装 Ruff、Black 这种 CLI 工具又可能考虑pipx。这就产生了一个非常明显的问题Python 的工具链比较碎片化。而 Rust 的体验就非常统一。例如cargonew my-projectcargoaddserdecargobuildcargoruncargotest所以 Astral 在 uv 的设计目标中提出了一个很有意思的方向Cargo for Python。也就是希望 Python 也拥有类似 Cargo 的统一项目管理体验。Astral 在 2024 年 8 月进一步宣布 uv 从单纯的 pip 替代品扩展到完整的 Python 项目、命令行工具、单文件脚本以及 Python 本身的管理。(Astral)三、为什么 uv 使用 Rust这是 uv 最大的特点之一。传统 Python 包管理工具大量使用 Python 实现而 uv 使用 Rust。为什么因为包管理器本身需要大量进行网络请求文件操作ZIP/TAR 解压包元数据解析依赖关系解析哈希计算缓存管理并发任务这些任务非常适合使用 Rust 构建。而且 uv 并不依赖 Python 才能运行。这意味着没有 Python ↓ 也可以安装 uv ↓ uv 安装 Python ↓ uv 创建虚拟环境 ↓ uv 安装项目依赖这就是一个非常重要的改变。官方文档也明确说明uv 可以在没有预先安装 Python 或 Rust 的情况下通过独立安装器进行安装。(Astral 文档)四、安装 uvLinux / macOS可以使用官方安装脚本curl-LsSfhttps://astral.sh/uv/install.sh|sh安装完成以后uv--version例如uv 0.x.xWindowsPowerShellpowershell-ExecutionPolicy ByPass-cirm https://astral.sh/uv/install.ps1 | iex也可以使用winget install--idastral-sh.uv-e官方目前还提供 Homebrew、Scoop、Docker、PyPI 等多种安装方式。(Astral 文档)五、第一条 uv 命令安装完成以后直接uv你会发现 uv 并不是只有uvinstall这么简单。它已经形成了一套完整的 CLIuv init uv add uv remove uv run uv sync uv lock uv export uv tree uv python uv venv uv pip uv tool uv build uv publish uv cache uv self官方 CLI 当前已经覆盖项目管理、依赖管理、Python 管理、工具管理、构建和发布等多个场景。(Astral 文档)六、创建第一个 Python 项目这是我最推荐新项目使用 uv 的方式。直接uv init my-project然后cdmy-project你会看到类似my-project/ ├── .gitignore ├── .python-version ├── README.md ├── main.py └── pyproject.toml其中最重要的是pyproject.toml它是现代 Python 项目的核心配置文件。七、uv add添加依赖比如我们需要安装requests以前可能pipinstallrequests现在uvaddrequestsuv 会自动完成依赖解析和环境同步。如果需要指定版本uvaddrequests2.30指定固定版本uvaddrequests2.32.3开发依赖也可以进行单独管理。例如uvadd--devpytest然后项目的pyproject.toml会记录依赖。这种方式比手动pipinstallxxx pip freezerequirements.txt更加适合现代项目。八、uv remove删除依赖如果不需要某个包uv remove requestsuv 会同时更新项目依赖配置以及环境。九、uv sync同步环境这是 uv 非常重要的一条命令uvsync它的核心思想是让当前环境与项目定义的依赖保持一致。例如你从 GitHub 拉下来一个项目gitclone xxxcdproject通常你需要pipinstall-rrequirements.txt而 uv 项目一般直接uvsyncuv 会根据项目配置和锁文件准备环境。十、uv.lock 是什么这是 uv 最重要的设计之一。项目通常会有pyproject.toml uv.lock其中pyproject.toml描述我想要什么依赖。例如dependencies [ requests2.30, fastapi0.100 ]而uv.lock描述最终到底安装哪些具体版本。例如fastapi 0.x.x requests 2.x.x starlette 0.x.x urllib3 2.x.x这样团队成员执行uvsync理论上可以得到更加一致的依赖环境。十一、uv lock如果你只是想更新锁文件uv lock它会重新进行依赖解析并更新uv.lock在团队开发中一般建议pyproject.toml uv.lock ↓ Git 提交 ↓ 其他开发者 ↓ uv sync这样环境一致性会明显提高。十二、uv run不用 activate 也能运行这是 uv 很舒服的一点。传统方式source.venv/bin/activate python main.pyWindows.venv\Scripts\activate python main.py使用 uvuv run python main.py甚至uv run pytest或者uv run ruff check.uv 会自动使用项目环境。所以很多情况下你甚至不需要手动 activate 虚拟环境。十三、uv run 的一个重要特点例如uv run pythonuv 会检查项目配置 ↓ 锁文件 ↓ 虚拟环境 ↓ 依赖 ↓ Python然后准备运行环境。这使得uv run python main.py成为非常适合项目执行的标准方式。十四、uv venv创建虚拟环境如果你仍然希望像传统 Python 一样手动创建环境uv venv默认会创建.venv/也可以指定 Pythonuv venv--python3.12甚至uv venv--python3.11官方文档也建议使用虚拟环境来隔离项目依赖。(Astral 文档)十五、uv python直接管理 Python这可能是 uv 最让人惊喜的能力之一。以前 Python 开发者可能需要pyenv conda 官方 Python installer Windows Store现在可以直接uv pythoninstall3.12安装 Python 3.12。安装 Python 3.11uv pythoninstall3.11一次安装多个uv pythoninstall3.113.12查看 Pythonuv python list查找 Pythonuv pythonfind固定项目 Python 版本uv python pin3.12官方文档目前支持 uv 自动安装和管理多个 Python 版本也支持 CPython、PyPy 等实现。(Astral 文档)十六、Python 版本固定例如项目要求Python 3.12可以uv python pin3.12然后项目中会出现.python-version这样团队成员进入项目后就能够知道这个项目推荐使用哪个 Python 版本。对于大型项目非常有用。十七、uv pip兼容传统 pip 工作流如果你暂时不想迁移整个项目也没关系。uv 提供了uv pip它提供与常见 pip 工作流相似的接口。例如uv pipinstallrequests卸载uv pip uninstall requests查看uv pip list查看具体包uv pip show requests冻结uv pip freeze检查uv pip check官方特别强调uv pip并不是调用 pip。它只是提供了一个兼容 pip 使用习惯的低层接口。(Astral 文档)十八、pip → uv pip如果你现在项目大量使用 pip可以非常平滑地迁移。原来pipinstallrequests变成uv pipinstallrequests原来pip uninstall requests变成uv pip uninstall requests原来pip list变成uv pip list原来pip freeze变成uv pip freeze这也是 uv 能够快速流行的重要原因之一迁移成本非常低。十九、requirements.txt 怎么办如果你的项目已经有requirements.txt可以uv pipinstall-rrequirements.txt也可以使用uv pipsyncrequirements.txt两者有一个重要区别。install更接近传统安装行为。而uv pipsync会尝试让环境与 requirements 文件保持一致多余的包可能会被移除。官方文档明确说明uv pip sync会删除 requirements 文件中未列出的包。(Astral 文档)二十、uv pip compile如果你的项目仍然使用requirements.in可以uv pip compile requirements.in-orequirements.txt例如requirements.in里面只有fastapi requests pydantic然后uv pip compile requirements.in-orequirements.txtuv 会解析完整依赖关系。最终生成requirements.txt里面可能包含大量间接依赖。这就类似于pip-tools的工作流。二十一、uv tree查看依赖关系项目依赖越来越复杂以后一个非常实用的命令就是uv tree例如my-project ├── fastapi │ ├── starlette │ └── pydantic │ └── annotated-types └── requests ├── urllib3 ├── certifi └── charset-normalizer这样可以快速理解一个 Python 包到底依赖了什么。排查为什么装了这么多包 为什么出现版本冲突 谁依赖了这个包都会非常方便。二十二、uv tool管理 Python CLI 工具Python 生态有大量 CLI 工具ruff black httpie yt-dlp pre-commit cookiecutter以前很多人会使用pipxinstallruff现在可以使用uv toolinstallruff运行uv tool run ruff check.或者简写uvx ruff check.这种方式特别适合我只想使用一个 Python CLI 工具不想把它安装到当前项目环境。二十三、uvx 是什么可以把uvx理解成临时运行 Python CLI 工具。例如uvx ruff check.你不需要先pipinstallruff也不需要污染当前项目环境。这对于开发工具非常方便。例如uvx black.或者uvx pytest二十四、uv run 单文件脚本uv 甚至可以管理单文件 Python 脚本。例如# hello.pyimportrequestsprint(requests.get(https://example.com))传统情况下pipinstallrequests python hello.py而 uv 可以让脚本声明自己的依赖。例如通过 PEP 723 内联元数据描述依赖然后uv run hello.pyuv 会根据脚本声明准备运行环境。官方 CLI 文档目前明确支持uv run --script以及 PEP 723 风格的脚本依赖管理。(Astral 文档)这对于数据处理脚本 自动化脚本 爬虫 AI Demo 一次性工具 运维脚本非常实用。二十五、uv cache为什么 uv 越用越快uv 有自己的缓存系统。可以查看uv cachedir管理缓存uv cache clean为什么缓存很重要假设你有项目 A 项目 B 项目 C三个项目都需要requests pydantic numpy传统方式可能需要重复下载或者重新处理。uv 会尽可能利用缓存。因此第一次安装 ↓ 下载 构建 缓存 ↓ 第二个项目 ↓ 命中缓存 ↓ 更快这也是 uv 在很多重复安装场景中速度非常快的重要原因。二十六、uv 的核心架构思路如果从整体上理解 uv可以把它看成uv │ ┌─────────────┼─────────────┐ ↓ ↓ ↓ Python管理 项目管理 包管理 │ │ │ uv python uv init uv add uv venv uv run uv remove uv sync uv lock uv tree uv export │ │ │ └─────────────┼─────────────┘ ↓ uv cache而对于传统 pip 用户还有uv pip │ ┌───────────┼───────────┐ ↓ ↓ ↓ install compile sync所以 uv 并不是简单的“一个更快的 pip。”现在更准确的理解应该是uv 是一个统一的 Python 工具链。二十七、uv 和 pip 的区别简单来看能力pipuv安装 Python 包✅✅依赖解析✅✅虚拟环境❌✅Python 版本管理❌✅项目初始化❌✅Lockfile传统方式较弱✅CLI 工具管理❌✅项目运行❌✅Rust 实现❌✅高性能缓存有缓存强调全局缓存工作流统一一般很强但这里需要注意pip 并没有“过时”。pip 仍然是 Python 官方生态中极其重要的基础工具。uv 的价值更像是在保留 pip 工作流兼容性的同时把 Python 项目管理体验进一步统一。二十八、uv 和 Poetry 有什么区别Poetry 也是非常成熟的 Python 项目管理工具。两者都可以项目管理 依赖管理 虚拟环境 锁文件但理念略有区别。Poetry 更早就走向完整 Python 项目管理工具。而 uv 的路线是高速包安装 ↓ 高速依赖解析 ↓ pip 兼容 ↓ 项目管理 ↓ Python 管理 ↓ 工具管理 ↓ 脚本管理因此 uv 更强调速度 统一工具链 低迁移成本。二十九、uv 和 Conda 有什么区别Conda 不只是 Python 包管理器。它还擅长Python C/C CUDA 系统库 科学计算环境尤其是机器学习 数据科学 CUDA 复杂二进制依赖Conda 依然非常有价值。而 uv 更偏向现代 Python 项目开发。如果你是FastAPI Django Flask AI Agent RAG 爬虫 自动化 Web 后端 普通 Python 软件uv 会非常舒服。如果你大量依赖CUDA 系统级科学计算库 Conda channel那么 Conda 仍然有它的优势。三十、一个真实项目应该怎么使用 uv假设我们开发一个AI RAG 项目第一步uv init rag-project进入cdrag-project指定 Pythonuv python pin3.12安装uvaddfastapi uvaddpydantic uvaddopenai uvaddchromadb开发依赖uvadd--devpytest uvadd--devruff同步uvsync运行uv run python main.py测试uv run pytest代码检查uv run ruff check.查看依赖uv tree最后提交pyproject.toml uv.lock .python-version到 Git。团队成员拿到项目以后gitclone xxxcdrag-project uvsync然后uv run python main.py整个过程就完成了。三十一、推荐的现代 Python 项目结构如果是我现在开始一个新的 Python 项目我会倾向于my-project/ │ ├── .venv/ ├── .python-version ├── pyproject.toml ├── uv.lock ├── README.md ├── src/ │ └── my_project/ │ ├── __init__.py │ └── main.py │ └── tests/ └── test_main.py然后日常开发uvsync运行uv run python-mmy_project.main安装依赖uvaddxxx删除uv remove xxx测试uv run pytest代码检查uv run ruff check.这套工作流已经非常接近Python 版 Cargo。三十二、最常用 uv 命令速查表如果不想记几十个命令可以先记下面这些项目uv init uv run uvadduv remove uvsyncuv lock uv treePythonuv python list uv pythoninstall3.12uv pythonfinduv python pin3.12uv python uninstall3.12虚拟环境uv venv uv venv--python3.12pip 兼容uv pipinstallxxx uv pip uninstall xxx uv pip list uv pip freeze uv pip check uv pip compile uv pipsync工具uv toolinstallruff uv tool list uv tool uninstall ruff uvx ruff缓存uv cachediruv cache clean版本uv--versionuv self update三十三、从 pip 迁移到 uv应该怎么做如果你已经有一个老项目requirements.txt不建议一上来就全部重构。可以先uv venv然后uv pipinstall-rrequirements.txt确认项目正常运行。之后再逐步迁移requirements.txt ↓ pyproject.toml ↓ uv.lock最终变成uvsyncuv run uvadduv remove如果项目非常老或者存在特殊安装逻辑则应该逐步迁移而不是一次性全部替换。三十四、uv 最大的价值到底是什么很多文章喜欢把 uv 的卖点总结成快这当然没错。但是我认为速度只是 uv 最容易被看到的优点而统一才是它真正重要的地方。以前pip venv virtualenv pip-tools pyenv pipx Poetry现在可以逐渐统一成uv │ ┌──────────┼──────────┐ ↓ ↓ ↓ Python Project Tools │ │ │ uv python uv add uv tool uv venv uv sync uvx uv run uv lock这才是 uv 最值得关注的地方。三十五、总结Python 的包管理正在发生变化过去 Python 开发的经典组合是python pip venv requirements.txt后来出现Poetry Pipenv Conda PDM Rye而 uv 的路线更加激进Python版本管理 虚拟环境 包安装 依赖解析 项目管理 Lockfile CLI工具 单文件脚本 构建发布全部逐渐整合到一个工具中。尤其对于新项目我认为非常值得尝试下面这一套uv init my-projectcdmy-project uv python pin3.12uvaddfastapi uvaddpydantic uvadd--devpytest uvsyncuv run python main.py uv run pytest你会发现整个 Python 项目的依赖管理过程变得非常简单。如果你以前一直使用pipinstallpython-mvenv pip freeze requirements.txt那么完全可以先从uv pipinstallxxx开始体验。如果感觉不错再逐渐迁移到uv init uvadduvsyncuv run uv lock这时候你就会真正理解为什么很多 Python 开发者会把 uv 称为“Python 生态里的 Cargo。”而这可能才是 uv 真正有意思的地方。
