uv:现代 Python 项目工作流

uv 是 Astral(写 Ruff 那家)用 Rust 写的 Python 工具链,一个二进制替代 pip + venv + pip-tools + pyenv + poetry 的核心功能。2024 年起爆发式普及,到 2026 年已经是多数新项目的默认选择。本文是我切换一年多后的实战笔记。

为什么换

痛点 pip + venv 时代 uv
装依赖慢 全量解析 + 串行下载 并行下载 + 全局缓存,快一个数量级
锁定依赖 要额外上 pip-tools / pipenv uv.lock 原生自带
多版本 Python pyenv 编译安装 uv python install 下载预编译,秒装
工具隔离 pipx uv tool / uvx

最直观的对比:冷启动一个装了几十个依赖的 venv,pip 要一两分钟,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"

项目工作流

初始化

uv init my-project --python 3.12
cd my-project

生成的是标准 pyproject.toml + main.py + .python-version,没有私有格式,随时可以换回任何标准工具链:

[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

加依赖(核心用法)

uv add fastapi uvicorn        # 加入 dependencies 并安装
uv add --dev pytest ruff      # 开发依赖
uv remove uvicorn             # 移除

每次 add/remove 都会同步更新 pyproject.toml 和 uv.lock,锁定文件提交进 Git。-lockfile 时代没有"我机器上能跑"。

同步与运行

uv sync                       # 按 lock 精确还原环境(CI/部署用)
uv run python main.py         # 在项目环境里执行,环境不存在会自动建
uv run pytest

uv run 是日常最高频命令——不用手动激活 venv,脚本直接跑。服务器上部署也就两条:

uv sync --frozen              # 严格按 lock 安装,不碰 pyproject
uv run gunicorn app:app

单文件脚本

3.9+ 的新玩法,单文件脚本可以直接声明依赖(PEP 723 内联元数据):

# /// script
# requires-python = ">=3.12"
# dependencies = ["httpx"]
# ///
import httpx
print(httpx.get("https://httpbin.org/get").status_code)
uv run fetch.py   # 自动装依赖到隔离环境后执行

写运维小脚本、给同事传单文件工具,比"先建 venv 再 pip install"优雅太多。

多版本 Python 管理

uv python list                  # 看可用版本
uv python install 3.12 3.13t    # 装两个:常规 3.12 + free-threaded 3.13
uv python pin 3.12              # 项目锁定 3.12(写入 .python-version)

预编译二进制直接下载,不用像 pyenv 那样本地编译等十分钟。

全局工具

替代 pipx:

uv tool install ruff
uvx ruff check .               # 临时运行,等于 pipx run

兼容旧习惯

存量项目不想大改?uv 保留了熟悉的接口:

uv venv                        # 建 .venv
uv pip install -r requirements.txt   # 传统方式装
uv pip freeze > requirements.txt

从 pip 平滑迁移的路径:先 uv venv + uv pip install 尝到速度,再逐步转 uv add 进 pyproject 管理。

踩坑记录

  1. uv sync 默认是"精确同步":会卸载不在 lock 里的包。想在环境里临时装点东西调试,用 uv pip install,别污染 lock;
  2. 私有源:UV_INDEX_URL 环境变量或 pyproject 里 [[tool.uv.index]] 配置内部镜像,CI 拉内网包必须配;
  3. Docker 多阶段构建记得利用缓存挂载:
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev
COPY . .
CMD ["uv", "run", "gunicorn", "app:app"]
  1. Windows 下路径带中文/空格的项目偶尔有边缘 bug,注意 UV_CACHE_DIR 可指定缓存位置。

总结

一套命令覆盖日常全部场景:

uv init && uv add xxx && uv run xxx   # 新项目
uv sync && uv run xxx                 # 拉下来就跑
uv tool install xxx                   # 装工具

工具链的意义在于让你忘记它的存在。从 pip 时代"先想想要不要建 venv"到现在"直接 uv run",这就是进步。

← 返回首页 · 历史归档