6.5 用 uv 管理 Python 与项目
上一节末尾提到了 uv,这一节把它讲透。uv 由 Astral 公司(Ruff 的作者)开发,目标很激进:用一个工具取代 pip、venv、pyenv、pipx、poetry。也就是说,装 Python、建虚拟环境、管理依赖、运行脚本、安装命令行工具——全部一个 uv 搞定。
安装 uv
uv 是独立程序,不依赖 Python(所以它才能反过来帮你装 Python):
Windows(PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
装完重开终端,验证:
uv --version
用 uv 安装和管理 Python 本身
这是 uv 和 pip 最大的不同之一:uv 可以直接帮你下载安装任意版本的 Python,不用再去官网下安装包,多版本共存也不冲突。
uv python install 3.12 # 安装 Python 3.12
uv python install 3.11 3.13 # 一次装多个版本
uv python list # 看本机有哪些 Python(包括系统里已有的)
想给某个项目固定 Python 版本:
uv python pin 3.12
这条命令会在当前文件夹生成一个 .python-version 文件,内容就是 3.12。之后在这个文件夹里执行任何 uv 命令,都会自动使用 3.12——同事拿到项目也一样,不用口头约定"这个项目要用 3.12 哦"。
💡 如果指定的版本本机没有,uv 会在需要时自动下载,完全无感。这解决了新手最头疼的"我电脑上的 Python 版本和教程/项目要求的不一样"问题。
创建虚拟环境(可指定 Python 版本)
uv 也能像 venv 一样单独建虚拟环境,而且可以指定用哪个版本的 Python:
uv venv # 用默认版本创建 .venv
uv venv --python 3.12 # 指定用 Python 3.12 创建
激活方式和上一节 venv 的完全一样(.venv\Scripts\Activate.ps1 等)。不过用 uv 的项目工作流时,通常不需要手动激活,往下看。
项目工作流:init、add、run
这是 uv 推荐的日常用法,一共四步:
1. 新建项目:
uv init myproject
cd myproject
uv 会生成这样的结构:
myproject/
├── .python-version # 固定的 Python 版本
├── pyproject.toml # 项目信息 + 依赖清单
├── README.md
└── main.py
也可以在创建时就指定 Python 版本:
uv init myproject --python 3.12
2. 添加依赖:
uv add requests # 添加依赖
uv add "requests==2.31.0" # 指定版本
uv remove requests # 移除依赖
第一次 uv add 时,uv 会自动创建 .venv 并安装库,速度飞快。依赖会写进 pyproject.toml:
[project]
name = "myproject"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"requests>=2.31.0",
]
同时生成一个 uv.lock 文件,精确锁定每个库(包括间接依赖)的版本,保证任何人任何时候装出来的环境一模一样。
3. 运行代码:
uv run main.py
uv run 会自动找到项目的 .venv 并用它来运行——不需要激活,这就是 uv 和传统 venv 用法最大的体验差异。
4. 还原环境(拿到别人的 uv 项目后):
uv sync
一条命令,按 uv.lock 把 Python 版本、虚拟环境、所有依赖全部装好。
pyproject.toml vs requirements.txt
| requirements.txt | pyproject.toml + uv.lock | |
|---|---|---|
| 记录方式 | pip freeze 手动导出,容易忘 | uv add 自动维护 |
| 记录内容 | 只有库和版本 | 项目信息、Python 版本要求、精确锁定 |
| 还原环境 | pip install -r | uv sync(连 Python 版本一起管) |
pyproject.toml 是 Python 官方标准(PEP 621),新项目都在用它。但 requirements.txt 在老项目里仍然大量存在,两个都要认识。uv 也兼容老格式:uv pip install -r requirements.txt 照样能用。
国内加速:换镜像源
uv 默认也是从国外源下载。在 pyproject.toml 里加一段(对当前项目生效):
[[tool.uv.index]]
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
default = true
想全局生效,可以设置环境变量 UV_DEFAULT_INDEX(Windows 在"编辑系统环境变量"里添加,macOS/Linux 写进 shell 配置文件):
UV_DEFAULT_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple
附赠技能:uvx 直接运行工具
有些第三方库其实是命令行工具(比如代码格式化工具 ruff)。uvx 可以不安装直接运行它们,用完即走,不污染任何环境:
uvx ruff check . # 临时下载并运行 ruff 检查代码
uvx pycowsay hello # 试试这个,会有惊喜
经常用的工具也可以正式装成全局命令:
uv tool install ruff
常见问题
Q:学了 uv,前面的 venv、pip 白学了吗?
没有。uv 底层概念完全一样(虚拟环境还是 .venv,装的还是 PyPI 上同样的库),只是把流程自动化了。而且公司老项目、别人的教程大量使用 pip + venv,看不懂等于寸步难行。
Q:uv add 和 uv pip install 有什么区别?
uv add 是项目工作流:写入 pyproject.toml 并更新锁文件,推荐日常使用。uv pip install 是给 pip 老用户的兼容接口,只装库不记录,行为和 pip 一样。
Q:uv 项目还需要 .gitignore 忽略什么?
和之前一样忽略 .venv/。但 pyproject.toml、uv.lock、.python-version 都要提交到 Git——它们正是别人还原你环境的依据。
练习
- 安装 uv,用
uv python list看看你机器上有哪些 Python,再用uv python install 3.12装一个新版本。 uv init uv_test --python 3.12创建项目,uv add requests,把上一节的 requests 示例代码放进main.py,用uv run main.py运行。- 打开
pyproject.toml和uv.lock,观察uv add前后它们的变化。 - 玩一下
uvx pycowsay hello。
本章小结
- uv 一个工具管所有:装 Python(
uv python install)、固定版本(uv python pin)、建环境(uv venv --python 3.12) - 项目四件套:
uv init建项目 →uv add加依赖 →uv run跑代码(免激活)→uv sync还原环境 - 依赖记录在
pyproject.toml(官方标准),uv.lock精确锁定版本 uvx免安装运行命令行工具- venv + pip 是基础和通用语言,uv 是效率升级,两者都要会
下一章:7.1 读写文件