Python uv 包管理器 2026:比 pip 快 10 倍的依赖管理终极指南

编程语言

Python 依赖管理的至暗时刻

每个 Python 开发者都经历过这些痛苦:

  • pip 安装慢如蜗牛:一个 Django 项目 pip install 动辄几分钟,依赖解析卡在 Collecting 阶段让人抓狂
  • poetry 配置复杂如天书pyproject.toml 的依赖分组、extras、source 配置让人头大,lock 文件冲突更是家常便饭
  • venv 手动管理繁琐python -m venv .venvsource .venv/bin/activatedeactivate……每个项目都要重复这套流程
  • Python 版本切换混乱:pyenv、conda、系统 Python 互相打架,which python 永远不知道指向哪个
  • 依赖锁定不可靠requirements.txt 没有锁文件,pip freeze > requirements.txt 生成的依赖包含间接依赖,环境无法复现

2024 年,Astral 团队(ruff 的创造者)推出了 uv——一个用 Rust 编写的 Python 包管理器,速度比 pip 快 10-100 倍。到 2026 年,uv 已经成为 Python 生态中最受瞩目的包管理工具,支持项目管理、虚拟环境、Python 版本管理、Monorepo 工作区等全栈能力。

本文将从核心概念出发,通过 5 大实战模式,带你全面掌握 uv 的使用。


核心概念速查

概念 说明 对应命令
项目管理 初始化项目、管理依赖声明 uv inituv adduv remove
虚拟环境 自动创建和管理 .venv uv venvuv sync
Python 版本管理 安装和切换 Python 解释器 uv python installuv python pin
依赖锁定 生成可复现的锁文件 uv lock(自动生成 uv.lock)
依赖解析 高性能解析依赖树 内置 Rust 解析器,10-100x 速度提升
工作区 Monorepo 多包管理 uv workspace
工具运行 临时安装并运行 CLI 工具 uv tool runuvx
脚本执行 内联依赖声明并运行脚本 uv run script.py
缓存管理 全局包缓存,避免重复下载 uv cache
导出依赖 导出为 requirements.txt 格式 uv export

五大核心挑战分析

挑战一:依赖解析速度

pip 使用回溯解析算法,复杂依赖图可能需要数分钟甚至解析失败。uv 采用基于 SAT 求解器的高性能解析器,通常在毫秒级完成解析。

挑战二:环境一致性

requirements.txt 不包含完整的依赖锁定信息,不同机器安装结果可能不同。uv 的 uv.lock 锁文件记录完整的依赖树哈希,确保任何环境都能精确复现。

挑战三:Python 版本碎片化

不同项目需要不同 Python 版本,pyenv + venv 的组合配置繁琐。uv 内置 Python 版本管理,一条命令安装切换,无需额外工具。

挑战四:Monorepo 依赖共享

多个子包之间有内部依赖关系,传统方案需要手动发布到私有 PyPI 或使用 pip install -e。uv workspace 原生支持 Monorepo,子包之间自动链接。

挑战五:CI/CD 缓存效率

pip 在 CI 中每次都要重新下载依赖,即使有缓存也经常 cache miss。uv 的全局缓存 + 内容寻址机制让 CI 缓存命中率接近 100%。


方案一:uv 安装与项目初始化

安装 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

# 使用 Homebrew
brew install uv

# 验证安装
uv --version
# uv 0.7.12 (2026 年最新稳定版)

项目初始化

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

# 查看项目结构
# my-project/
# ├── .python-version    # Python 版本锁定
# ├── pyproject.toml     # 项目配置和依赖声明
# ├── uv.lock            # 依赖锁文件(自动生成)
# ├── hello.py           # 示例入口文件
# └── .venv/             # 虚拟环境(自动创建)

依赖管理

# 添加依赖
uv add fastapi
uv add "sqlalchemy>=2.0"
uv add --dev pytest
uv add --dev ruff

# 添加可选依赖组
uv add --optional ml torch

# 移除依赖
uv remove pytest

# 同步依赖(安装 pyproject.toml 中声明的所有依赖)
uv sync

# 仅同步生产依赖(排除 dev)
uv sync --no-dev

# 同步指定分组
uv sync --group ml

pyproject.toml 结构

[project]
name = "my-project"
version = "0.1.0"
description = "A modern Python project"
requires-python = ">=3.12"
dependencies = [
    "fastapi>=0.115.0",
    "sqlalchemy>=2.0",
]

[project.optional-dependencies]
ml = [
    "torch>=2.5",
    "transformers>=4.45",
]

[tool.uv]
dev-dependencies = [
    "pytest>=8.0",
    "ruff>=0.8",
]

[tool.uv.sources]
my-private-pkg = { git = "https://github.com/myorg/my-private-pkg.git", tag = "v1.0.0" }

运行项目

# 在虚拟环境中运行脚本
uv run python hello.py

# 运行模块
uv run python -m my_project.main

# 运行带内联依赖声明的脚本
uv run --with requests python fetch_data.py

方案二:虚拟环境与 Python 版本管理

虚拟环境管理

# 创建虚拟环境(默认使用 .venv 目录)
uv venv

# 指定 Python 版本创建
uv venv --python 3.12

# 指定虚拟环境路径
uv venv /path/to/.venv

# 激活虚拟环境
# macOS / Linux
source .venv/bin/activate
# Windows
.venv\Scripts\activate

# uv sync 会自动创建虚拟环境
uv sync

Python 版本管理

# 查看可用 Python 版本
uv python list

# 安装指定 Python 版本
uv python install 3.12
uv python install 3.13

# 安装特定实现
uv python install pypy3.10
uv python install graalpy3.11

# 固定项目 Python 版本(写入 .python-version)
uv python pin 3.12

# 查看已安装版本
uv python list --only-installed

# 查找 Python 解释器路径
uv python find 3.12

# 临时使用指定版本运行
uv run --python 3.13 python --version

.python-version 文件

3.12

这个文件会被 uv 自动读取,确保团队成员使用一致的 Python 版本。配合 uv sync,新人 clone 项目后只需一条命令即可搭建完整环境。

多版本并行场景

# 项目 A 使用 Python 3.12
cd project-a
uv python pin 3.12
uv sync

# 项目 B 使用 Python 3.13
cd project-b
uv python pin 3.13
uv sync

# 两个项目互不干扰,无需 pyenv 切换

方案三:从 pip/requirements.txt 和 poetry/pyproject.toml 迁移

从 pip + requirements.txt 迁移

# 方式一:直接在现有项目中初始化
cd existing-project
uv init
# uv 会检测到已有的 requirements.txt 并自动导入

# 方式二:手动导入依赖
uv add $(cat requirements.txt | grep -v "^#" | grep -v "^$" | tr "\n" " ")

# 方式三:使用 uv pip 兼容模式(过渡期使用)
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt

# 导出回 requirements.txt 格式
uv export > requirements.txt
uv export --no-dev > requirements-prod.txt

从 poetry 迁移

# uv 直接读取 poetry 的 pyproject.toml
cd poetry-project
uv init
# uv 会自动识别 [tool.poetry.dependencies] 并迁移

# 手动迁移步骤
# 1. 备份 poetry.lock
cp poetry.lock poetry.lock.bak

# 2. 将 poetry 依赖格式转为 PEP 621 格式
# poetry 格式:
#   [tool.poetry.dependencies]
#   fastapi = "^0.115.0"
# PEP 621 格式:
#   [project]
#   dependencies = ["fastapi>=0.115.0"]

# 3. 生成 uv.lock
uv lock

# 4. 同步依赖
uv sync

poetry 到 uv 的 pyproject.toml 转换脚本

import tomllib
import tomli_w
from pathlib import Path


def migrate_poetry_to_uv(pyproject_path: str = "pyproject.toml"):
    ""将 poetry 格式的 pyproject.toml 转换为 uv 兼容格式""
    path = Path(pyproject_path)
    data = tomllib.loads(path.read_text(encoding="utf-8"))

    poetry_deps = data.get("TOOL", {}).get("poetry", {}).get("dependencies", {})
    poetry_dev_deps = (
        data.get("TOOL", {})
        .get("poetry", {})
        .get("group", {})
        .get("dev", {})
        .get("dependencies", {})
    )

    def convert_version(version_spec: str) -> str:
        if isinstance(version_spec, dict):
            return version_spec.get("version", "*")
        if version_spec.startswith("^"):
            base = version_spec[1:]
            parts = base.split(".")
            upper = f"{int(parts[0]) + 1}.0.0"
            return f">={base},<{upper}"
        if version_spec.startswith("~"):
            base = version_spec[1:]
            parts = base.split(".")
            upper = f"{parts[0]}.{int(parts[1]) + 1}.0"
            return f">={base},<{upper}"
        return version_spec

    dependencies = []
    for name, version in poetry_deps.items():
        if name == "python":
            data.setdefault("project", {})["requires-python"] = f">={version}"
            continue
        dep = convert_version(version)
        dependencies.append(f"{name}{dep}" if dep != "*" else name)

    data.setdefault("project", {})["dependencies"] = dependencies

    dev_dependencies = []
    for name, version in poetry_dev_deps.items():
        dep = convert_version(version)
        dev_dependencies.append(f"{name}{dep}" if dep != "*" else name)

    if dev_dependencies:
        data.setdefault("TOOL", {}).setdefault("uv", {})[
            "dev-dependencies"
        ] = dev_dependencies

    if "poetry" in data.get("TOOL", {}):
        del data["TOOL"]["poetry"]

    path.write_text(tomli_w.dumps(data), encoding="utf-8")
    print(f"迁移完成: {dependencies=}, {dev_dependencies=}")


if __name__ == "__main__":
    migrate_poetry_to_uv()

从 pipenv 迁移

# 导出 Pipfile 依赖为 requirements.txt
pipenv requirements > requirements.txt

# 使用 uv 初始化并导入
uv init
uv add $(cat requirements.txt | tr "\n" " ")
uv sync

方案四:Monorepo 与工作区管理

工作区初始化

# 创建 Monorepo 根目录
mkdir my-monorepo && cd my-monorepo
uv init --workspace

# 创建子包
uv init --package libs/core
uv init --package libs/api
uv init --package apps/web

# 项目结构
# my-monorepo/
# ├── pyproject.toml          # 工作区根配置
# ├── uv.lock                 # 全局锁文件(统一管理)
# ├── libs/
# │   ├── core/
# │   │   ├── pyproject.toml
# │   │   └── src/core/
# │   └── api/
# │       ├── pyproject.toml
# │       └── src/api/
# └── apps/
#     └── web/
#         ├── pyproject.toml
#         └── src/web/

根 pyproject.toml 配置

[tool.uv.workspace]
members = [
    "libs/core",
    "libs/api",
    "apps/web",
]

[tool.uv.sources]
core = { workspace = true }
api = { workspace = true }

子包 pyproject.toml

# libs/core/pyproject.toml
[project]
name = "core"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "pydantic>=2.9",
]

# libs/api/pyproject.toml
[project]
name = "api"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "core",
    "fastapi>=0.115.0",
]

# apps/web/pyproject.toml
[project]
name = "web"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "core",
    "api",
    "uvicorn>=0.32.0",
]

工作区操作

# 同步整个工作区
uv sync

# 仅同步指定子包
uv sync --package api

# 在指定子包中运行命令
uv run --package api python -m api.main

# 为指定子包添加依赖
uv add --package api httpx

# 构建指定子包
uv build --package core

# 发布指定子包
uv publish --package core

工作区依赖图验证

# 查看依赖树
uv tree

# 检查依赖冲突
uv lock --check

# 更新指定依赖
uv lock --upgrade-package fastapi

方案五:CI/CD 集成与 Docker 优化

GitHub Actions 集成

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4
        with:
          version: "latest"
          enable-cache: true
          cache-dependency-glob: "uv.lock"

      - name: Set up Python
        run: uv python install 3.12

      - name: Install dependencies
        run: uv sync --frozen

      - name: Run linter
        run: uv run ruff check .

      - name: Run tests
        run: uv run pytest --cov=src --cov-report=xml

      - name: Upload coverage
        uses: codecov/codecov-action@v4

GitLab CI 集成

# .gitlab-ci.yml
stages:
  - test
  - build

test:
  stage: test
  image: python:3.12-slim
  before_script:
    - pip install uv
    - uv python install 3.12
    - uv sync --frozen
  script:
    - uv run ruff check .
    - uv run pytest --cov=src
  cache:
    key:
      files:
        - uv.lock
    paths:
      - .venv/
      - ~/.cache/uv/

build:
  stage: build
  image: python:3.12-slim
  before_script:
    - pip install uv
  script:
    - uv build
  artifacts:
    paths:
      - dist/

Docker 多阶段构建优化

# Dockerfile
FROM ghcr.io/astral-sh/uv:latest AS uv

FROM python:3.12-slim AS deps
COPY --from=uv /uv /usr/local/bin/uv

WORKDIR /app

COPY pyproject.toml uv.lock ./

RUN uv sync --frozen --no-install-project --no-dev

FROM python:3.12-slim AS runtime

WORKDIR /app

COPY --from=deps /app/.venv /app/.venv

COPY . .

ENV PATH="/app/.venv/bin:$PATH"
ENV VIRTUAL_ENV="/app/.venv"

CMD ["python", "-m", "my_project.main"]

Docker Compose 开发环境

# docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    volumes:
      - .:/app
      - uv-cache:/root/.cache/uv
    environment:
      - PYTHONUNBUFFERED=1
    command: uv run uvicorn my_project.main:app --host 0.0.0.0 --reload

volumes:
  uv-cache:

CI 缓存优化技巧

# 使用 --frozen 确保不修改锁文件(CI 环境必须)
uv sync --frozen

# 使用 --no-dev 减少安装量
uv sync --frozen --no-dev

# 离线安装(依赖已缓存时)
uv sync --frozen --offline

常见陷阱指南

陷阱一:混用 pip 和 uv

❌ 在 uv 管理的项目中用 pip install 安装依赖,绕过 uv 的依赖管理

✅ 始终使用 uv add 添加依赖,uv sync 同步环境。如需临时安装,用 uv pip install(兼容模式)

陷阱二:忽略 uv.lock 提交

❌ 将 uv.lock 加入 .gitignore,导致团队成员依赖版本不一致

✅ 将 uv.lock 提交到版本控制,确保所有环境使用相同的依赖版本。CI 中使用 --frozen 防止意外更新

陷阱三:忘记固定 Python 版本

❌ 不设置 .python-version,不同开发者使用不同 Python 版本导致兼容性问题

✅ 使用 uv python pin 3.12 固定版本,并将 .python-version 提交到仓库

陷阱四:全局安装污染

❌ 使用 uv tool install 安装大量全局工具,版本冲突难以排查

✅ 项目级工具使用 uv run --with 临时安装运行;全局工具仅安装高频使用的(如 ruff、black)

陷阱五:Docker 中不利用缓存层

❌ 先 COPY 全部代码再 uv sync,每次代码变更都重新安装依赖

✅ 先 COPY pyproject.toml + uv.lock,再 uv sync,最后 COPY 代码。利用 Docker 缓存层避免重复安装


错误排错表

错误现象 可能原因 解决方案
error: No virtual environment found 未创建虚拟环境 运行 uv syncuv venv 自动创建
error: Failed to download package 网络问题或 PyPI 源不可达 配置镜像源:uv pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
error: Python 3.12 not found 未安装对应 Python 版本 运行 uv python install 3.12
error: Lockfile is out of date pyproject.toml 更新但未重新 lock 运行 uv lock 更新锁文件
error: Resolution failed 依赖版本冲突 检查 pyproject.toml 中的版本约束,使用 uv tree 查看依赖树
error: Package not found in workspace 工作区成员配置错误 检查 [tool.uv.workspace]members 路径
uv sync 速度慢 缓存未命中或网络延迟 检查缓存目录权限,配置镜像源,使用 --offline 模式
error: Hash mismatch 依赖包被篡改或缓存损坏 运行 uv cache clean 清除缓存后重试
error: Cannot activate venv 虚拟环境损坏 删除 .venv 目录后重新 uv sync
error: Unsupported Python version Python 版本不满足 requires-python 运行 uv python install 安装满足要求的版本

高级优化技巧

1. 镜像源加速

# 配置清华镜像源(中国大陆推荐)
uv pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

# 或在 pyproject.toml 中配置
# [tool.uv]
# index-url = "https://pypi.tuna.tsinghua.edu.cn/simple"

# 多源配置(私有 PyPI + 公共源)
# [tool.uv]
# extra-index-url = ["https://pypi.mycompany.com/simple/"]

2. 缓存管理

# 查看缓存信息
uv cache dir

uv cache list

# 清除缓存
uv cache clean

# 清除特定包的缓存
uv cache clean numpy

# 查看缓存大小
du -sh $(uv cache dir)

3. 离线环境部署

# 导出依赖到 vendor 目录
uv export --no-dev > requirements.txt
uv pip download -r requirements.txt -d vendor/

# 离线安装
uv pip install --no-index --find-links vendor/ -r requirements.txt

4. 脚本内联依赖

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

import requests
from rich import print

response = requests.get("https://httpbin.org/json")
print(response.json())
# 直接运行,uv 自动安装依赖
uv run script.py

5. 依赖安全审计

# 检查已知漏洞
uv audit

工具对比选型

维度 uv pip poetry pdm conda
依赖解析速度 极快(Rust) 慢(回溯) 中等
虚拟环境管理 内置 需 venv 内置 内置 内置
Python 版本管理 内置 需 pyenv 需 pyenv 内置 内置
锁文件 uv.lock poetry.lock pdm.lock
Monorepo 支持 原生工作区 不支持 不支持 有限 不支持
CI 缓存友好 极好 一般
配置复杂度
生态成熟度 快速成长 最成熟 成熟 成长中 成熟
学习曲线 平缓 平缓 陡峭 中等 陡峭
包数量 PyPI 全量 PyPI 全量 PyPI 全量 PyPI 全量 Anaconda + PyPI
跨语言支持 仅 Python 仅 Python 仅 Python 仅 Python 多语言(C/C++/R)
推荐指数 ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐

选型建议

  • 新项目首选 → uv(全栈能力、极速体验)
  • 已有 poetry 项目 → 逐步迁移到 uv(兼容读取 poetry 配置)
  • 数据科学/ML 项目 → uv + conda 互补(uv 管理纯 Python 包,conda 管理 C/C++ 依赖)
  • 简单脚本/一次性任务 → uv run(无需初始化项目)

相关工具推荐

在 Python 项目开发中,以下 工具库 工具可以帮到你:

  • JSON 格式化 — 格式化 API 响应和配置文件,排查 pyproject.toml 中的 JSON 数据问题
  • Hash 计算 — 计算依赖包哈希值,验证下载完整性
  • cURL 转代码 — 将 API 请求一键转为 Python 代码,快速构建 HTTP 客户端

Python 依赖管理经历了从 easy_installpip,从 requirements.txtpoetry.lock 的漫长演进。uv 的出现不是简单的替代,而是将 Rust 的高性能与 Python 的易用性完美结合,让依赖管理从「不得不忍受的痛点」变成「几乎无感的体验」。2026 年,uv 已经准备好成为你的默认选择。

本站提供浏览器本地工具,免注册即可试用 →

#Python包管理#uv工具#pip替代#Python依赖管理#2026#编程语言