--- tags: [uv, python, package-manager, virtualenv, dependency-management] create time: 2026-05-05 15:30 --- # UV — Fast Python Package Manager ## 概述 UV 是 Astral(Ruff 的出品方)开发的极速 Python 包管理工具,用 Rust 编写。它同时承担 **包安装器**、**虚拟环境管理器** 和 **解析器** 三种角色,兼容 `pip`/`venv`/`virtualenv` 的工作流,但在性能上实现了数量级提升。 > [!tip] 为什么选择 UV? > pip + venv + virtualenv + poetry 需要多个工具协作——每个工具职责不同、配置分散。UV 将安装包、管理虚拟环境、生成 lock 文件、管理多版本项目统一到一个 CLI 中。基准测试显示,`uv pip install` 比 pip 快 **10~100 倍**。 > [!question] 思考 > 一个包管理工具为什么要重写为 Rust? > —— Python 生态的依赖解析和下载是 I/O 密集型任务。Rust 提供了零成本抽象和极低的运行时开销,配合并发下载能力,这正是 pip(单线程 CPython 实现)难以企及的。 ## 核心概念 ### UV 与 pip/venv/poetry 的关系 ```mermaid graph TD subgraph Traditional["传统工具链"] P[pip — 包安装] V[venv/virtualenv — 虚拟环境] PO[poetry/pip-tools — 依赖锁定] end subgraph UVChain["UV 工具链"] A[uv pip — 包安装] B[uv venv — 虚拟环境] C[uv lock — 依赖锁定] end Traditional --> D["三个独立工具配置分散"] UVChain --> E["单一二进制零依赖"] classDef old fill:#fef3c7,color:#92400e classDef new fill:#dcfce7,color:#166534 classDef diff fill:#dbeafe,color:#1e3a8a class P,V,PO old class A,B,C new class D,E diff ``` ### 兼容模式 vs 原生模式 UV 支持两种使用方式: | 模式 | 核心命令 | 适用场景 | |------|----------|----------| | **`uv pip` 兼容模式** | `uv pip install` / `uv pip compile` | 从 pip 迁移,完全兼容 `requirements.txt` | | **UV 原生模式** | `uv add` / `uv lock` / `uv run` | 新项目推荐,基于 `pyproject.toml` 现代化工作流 | > [!note] `uv pip` 与原生命令的区别 > - `uv pip install` 安装到系统或虚拟环境中的 site-packages,行为与 pip 一致 > - `uv add` 直接修改 `pyproject.toml` 中的依赖声明,并自动更新 `uv.lock`,适合有明确项目结构的项目 > - 生产环境建议优先使用原生模式,因为 lock 文件确保所有开发者使用完全一致的依赖树 ### pyproject.toml 中的 UV 配置 UV 使用标准 `pyproject.toml`,通过 `[tool.uv]` 表进行专属配置: ```toml [project] name = "my-project" version = "0.1.0" requires-python = ">=3.11" dependencies = [ "fastapi>=0.110.0", "httpx", ] [tool.uv] dev-dependencies = [ "pytest>=8.0", "ruff>=0.4.0", ] # 指定 Python 源 [[tool.uv.index]] name = "pypi" url = "https://pypi.org/simple/" # 私有源(如需) #[[tool.uv.sources]] #my-private-pkg = { index = "internal" } ``` ## 安装 ### 操作系统安装命令 ```bash # 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" # Homebrew / apt / scoop brew install uv # macOS apt install uv # Ubuntu(需先添加仓库) scoop install uv # Windows ``` > [!tip] 验证安装 > 安装完成后运行 `uv --version`,确认版本 ≥ 0.5.0。首次运行时 UV 会自动下载所需的 Python 版本并缓存,后续启动无需等待。 ## 虚拟环境管理 ### 创建与管理虚拟环境 ```bash # 创建虚拟环境(默认使用 .venv 目录) uv venv # 指定 Python 版本(自动下载缺失版本) uv venv --python 3.12 # 指定目标路径 uv venv ./.venv-prod ``` 创建成功后,激活方式与传统 venv 一致: ```bash # macOS / Linux source .venv/bin/activate # Windows PowerShell .venv\Scripts\Activate.ps1 ``` ### uv run — 零激活执行 ```bash # 在虚拟环境中直接运行命令,无需手动激活 uv run python main.py # 传递参数 uv run pytest tests/ -v # 交互式 REPL uv run python -i ``` > [!tip] 为什么推荐使用 `uv run`? > 省去了 `source .venv/bin/activate` 和 `deactivate` 的手动步骤。CI/CD、脚本调用、编辑器集成都可以通过 `uv run` 一次性完成——它会自行查找 `.venv` 或使用 `pyproject.toml` 中声明的环境。 ## 包管理与依赖 ### 原生模式:`uv add` / `uv remove` ```bash # 添加生产依赖(写入 pyproject.toml + 更新 uv.lock) uv add fastapi httpx # 添加开发依赖(写入 dev-dependencies) uv add --dev pytest ruff mypy # 指定精确版本或范围 uv add "requests>=2.31,<3" uv add flask==3.0.0 # 从 Git 仓库安装 uv add git+https://github.com/user/repo.git@branch # 移除依赖 uv remove httpx ``` ### `pip` 兼容模式:`uv pip` ```bash # 安装 requirements.txt(行为与 pip install -r 一致) uv pip install -r requirements.txt # 生成锁文件(类似 pip-compile) uv pip compile requirements.in -o requirements.locked.txt # 卸载包 uv pip uninstall requests ``` ### 版本解析策略 UV 使用基于 **回溯** 的高性能依赖解析器(由 pubgrub 算法驱动),与 Poetry 的行为语义相同: ```mermaid flowchart LR A["用户请求: fastapi>=0.110 + httpx"] --> B{"解析依赖树"} B --> C["发现冲突: A 要求 urllib3>=2, B 要求 urllib3<2"] C --> D["尝试替换 B 为兼容版本"] D -->|"解决"| E["输出唯一可行解 → uv.lock"] D -->|"无解"| F["报错: 不可解析"] classDef ok fill:#dcfce7,color:#166534 classDef fail fill:#f99,color:#7f1d1d class E ok class F fail ``` ## Lock 文件 ### `uv.lock` 的作用 `uv.lock` 是 UV 的依赖锁文件,记录的是经过解析后 **每一个子依赖的确切版本号**(不仅是顶层依赖)。这确保了: 1. 不同机器、不同时间安装得到完全相同的依赖树 2. CI/CD 环境可复现构建结果 3. 避免 "在我机器上是好的" 问题 ### 典型工作流 ```bash # 新增依赖(自动生成或更新 lock 文件) uv add httpx # 手动更新 lock 文件(不改变 pyproject.toml,只更新锁定版本到最新兼容版) uv lock # 安装 lock 文件中锁定的所有依赖 uv sync # 同步但排除 dev 依赖(生产环境) uv sync --no-dev ``` > [!info] uv sync vs pip install -r > - `uv sync` 会严格对照 `uv.lock` 安装——移除多余的、更新过期的、安装缺失的 > - `pip install -r` 只看 `requirements.txt`,不会主动清理已安装但未声明的包 > - 推荐始终使用 `uv sync` 代替 `pip install -e .` ## 多项目工作区(Workspace) UV 支持 Monorepo 风格的多项目组织: ```toml # pyproject.toml at workspace root [project] name = "workspace-root" version = "0.1.0" requires-python = ">=3.11" [tool.uv.workspace] members = ["packages/*"] optional-groups = ["docs"] ``` ```toml # packages/web/pyproject.toml [project] name = "web-service" dependencies = ["shared-lib"] # 引用 workspace 内的其他项目 ``` ```toml # packages/lib/pyproject.toml [project] name = "shared-lib" ``` ```bash # 在工作区根目录操作 uv lock # 解析整个工作区的依赖 uv sync # 安装所有成员包的依赖 uv add -p web-service fastapi # 只为特定成员添加依赖 ``` ## 实战示例 ### 创建一个 FastAPI 项目 ```bash # ① 创建项目并初始化 venv uv init my-api cd my-api uv venv --python 3.12 # ② 添加依赖 uv add fastapi uvicorn httpx uv add --dev ruff pytest # ③ 运行项目 uv run uvicorn main:app --reload # ④ 运行测试 uv run pytest tests/ -v ``` ### CI/CD 流水线集成 ```yaml # .github/workflows/ci.yml(简化版) jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install UV run: curl -LsSf https://astral.sh/uv/install.sh | sh - name: Sync dependencies run: uv sync --all-extras --frozen - name: Run tests run: uv run pytest tests/ -v - name: Lint run: uv run ruff check . ``` > [!warning] `--frozen` 标志的含义 > 加上 `--frozen` 时,如果 `uv.lock` 不存在或与 `pyproject.toml` 不一致,命令会直接失败而非自动更新。这在 CI 中很重要——确保 lock 文件的变更必须经过代码审查提交。 ## 常用命令速查 | 命令 | 说明 | 等价命令 | |------|------|----------| | `uv add ` | 添加依赖到 pyproject.toml | `uv pip install` | | `uv remove ` | 从依赖中移除 | `uv pip uninstall` | | `uv sync` | 按 lock 文件同步环境 | `pip install -e .` | | `uv lock` | 生成/更新 lock 文件 | `poetry lock` | | `uv run ` | 在环境内执行命令 | `source .venv/bin/activate && cmd` | | `uv venv` | 创建虚拟环境 | `python -m venv .venv` | | `uv python list` | 列出可安装的 Python 版本 | `pyenv versions` | | `uv python install 3.12` | 下载并缓存指定 Python | `pyenv install 3.12` | | `uv pin 3.11` | 锁定项目 Python 版本 | 设置 `.python-version` | | `uv export` | 导出为 requirements.txt | `pip freeze > req.txt` | ## 与其他工具的对比 | 维度 | pip + venv | Poetry | uv | |------|-----------|--------|-----| | 语言 | Python | Python | Rust | | 安装速度 | 慢(单线程) | 中等 | ⚡ 极快(并发) | | 虚拟环境 | `venv` 独立命令 | `poetry env` | `uv venv` 内置 | | Lock 文件 | 需 pip-compile | `poetry.lock` | `uv.lock` | | pyproject.toml | 第三方支持 | ✅ 原生 | ✅ 原生 | | 多项目/Workspace | ❌ | ✅ | ✅ | | Python 版本管理 | ❌ 需 pyenv | ❌ 需 pyenv | ✅ `uv python install` | | 依赖大小 | 无额外依赖 | 较重 | 单个二进制 ~15MB | | 成熟度 | 事实标准 | 高 | 快速迭代中 | > [!info] 迁移建议 > - **pip 用户** → 直接使用 `uv pip` 命令获得加速,零迁移成本 > - **Poetry 用户** → `uv` 的 `add/sync/lock` 工作流与 Poetry 高度相似,学习曲线平缓 > - **新项目** → 直接用 `uv` 原生命令 + `pyproject.toml` + `uv.lock` ## 关联笔记 - [[hzh/DEV/Husky]] — Git Hooks 管理(可与 uv run 结合在 pre-commit 中运行 lint)