配环境有多恶心,无需多言,很多 Python 项目真正“拖慢开发效率”的,并不是写代码本身,而是配环境:
- 新机器/新环境装依赖,时间长且不可控
- 依赖多、约束复杂时,解析与冲突处理很慢
- requirements.txt 能用,但环境一致性仍然容易出问题(装多了、漏装了、版本漂移)
一、pip 的痛点:慢,不只是“下载慢”
1)安装慢
pip 的体验经常是:网络下载 + 依赖解析 + 本地构建混在一起,项目越大越明显。
2)依赖解析与冲突处理慢
当依赖树复杂(版本约束多、可选依赖多、历史包多)时,解析回溯会明显拉长等待时间,最后还可能以冲突告终。
二、uv :Astral 出品,Rust 编写,目标就是“更快、更统一”
uv 是 Astral 开发的 Python 包与项目管理工具,使用 Rust 实现。它提供了 uv pip 这套接口,目标是“尽可能不改变你的工作流”,但带来显著速度提升。官方项目说明里直接提到:迁移到 uv 并保留原有 pip 工作流的同时,可以获得 10–100 倍加速。
此外,uv 还强调了统一工具链的方向:同一个工具里覆盖常见的虚拟环境创建、依赖安装、锁定与同步等能力。
图片
三、实操指南:把 uv 用起来(从安装到替代 pip)
1)安装 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 --version
2)创建虚拟环境:uv venv
在项目目录下:
uv venv
uv 默认使用 .venv,后续执行 uv 命令会自动识别并使用该环境。
需要指定 Python 版本时:
uv venv --python 3.11
若系统无该版本,uv 也支持自动下载对应 Python
3)安装依赖:uv pip install
和 pip 几乎一致:
uv pip install numpy pandas
装 requirements.txt:
uv pip install -r requirements.txt
4)更推荐的“无缝替代”方式:用 uv pip sync 保证环境一致
很多人以为 pip install -r requirements.txt 就能复现环境,但现实里常见问题是:环境里可能残留“清单之外”的包,导致线上线下差异、实验不可复现。
uv 文档明确指出:uv pip install 不会主动移除多余依赖;要让环境严格匹配清单,更适合用 uv pip sync。
因此,如果你现有项目以 requirements.txt 为准,推荐替换为:
uv venv
uv pip sync requirements.txt
这基本就是最小迁移成本,同时显著提升安装与解析体验。
5)你已经有 requirements.txt:迁移清单
把你项目里原先的:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
替换为:
uv venv
source .venv/bin/activate
uv pip sync requirements.txt
如果你暂时不想引入sync,也可以先用:
uv pip install -r requirements.txt
但要明确:它更像 pip 的“增量安装”,一致性不如 sync。
四、总结:谁应该立刻尝试 uv
- 依赖多、装环境频繁(科研/工程都很常见)
- 团队协作需要更强的可复现性
- 你已经受够 pip 在解析和安装上的时间成本
迁移成本方面,uv pip 的“类 pip 接口”就是为了让你几乎不用改习惯;而速度收益与更规范的“sync”流程,是它最现实的价值点。
五、两条迁移路线:按你的“改动意愿”选择
路线 A:低改动(继续用 requirements.txt,但换成 uv 执行)
这是最适合大多数人的第一步:不改文件、不改习惯。
推荐工作流:
uv venv
source .venv/bin/activate
uv pip sync requirements.txt
补充两个关键点:
- uv 默认更“强制”你使用虚拟环境:它会优先使用当前激活环境,或自动寻找项目目录(及父目录)中的 .venv。
- uv pip 并不调用 pip;它只是提供了接近 pip 的“低层接口”来提升兼容与迁移体验。
路线 B:中改动(升级为 uv Project:pyproject.toml + uv.lock)
如果你希望把“可复现”做得更彻底(尤其是团队协作、论文复现实验、线上部署),建议进入 uv 的 project 工作流:依赖写进 pyproject.toml,版本锁定在 uv.lock,环境通过 uv sync 对齐。官方迁移指南明确就是围绕这套结构展开。
一个最小示例:在现有目录初始化(或新建项目)uv init添加依赖(会写入 pyproject.toml)uv add numpy pandas生成/更新锁文件uv lock同步环境(默认“exact”,会移除 lockfile 之外的包)uv sync
uv 文档说明:项目在首次运行 uv run / uv sync / uv lock 时,会创建 .venv 与 uv.lock,并保持环境与锁文件同步。
六、常见坑位与排查清单
1)“为什么我用 uv 装包失败,pip 却能装?”
uv 在一些行为上会比 pip 更严格,并且 uv pip 并不保证 100% 复刻 pip 的所有参数与边缘行为。官方明确提醒:越偏离常见工作流,越可能遇到差异,建议查阅兼容性指南。
可操作建议:
- 尽量使用常见的 requirements/pyproject 工作流;
- 遇到问题,先定位是不是“索引/构建/预发布版本”等典型差异点(见下)。
2)多索引(公司私服 + PyPI)场景:选择策略与 pip 不同
如果你同时用了多个 index(如 --extra-index-url),uv 与 pip 的候选版本合并策略可能不同:uv 会按顺序找到第一个包含该包的 index 后就停止继续搜;pip 则倾向于合并来自多个 index 的候选版本。
这类差异在企业内网、私有包仓库里非常常见。
- 先确认包到底来自哪个 index;
- 必要时考虑使用“为特定包固定 index”的方式(uv 文档在兼容性章节也提到相关能力)。
3)PEP 517 构建隔离导致的安装失败
uv 默认使用 PEP 517 的 build isolation(类似 pip install --use-pep517),有些老包的构建依赖声明不完整会导致失败。兼容性指南给出的“逃生舱”是:预装构建依赖,再用 --no-build-isolation。
示例(按文档思路改写):
uv pip install wheel
uv pip install --no-build-isolation <package>
4)uv sync 会不会把我手动装的包“删掉”?
会的(默认)。uv sync 默认是 “exact” 同步:会移除 lockfile 不包含的包;如果你希望保留额外包,使用 --inexact。
5)虚拟环境与 .venv 的自动发现机制
uv 在环境发现上非常“工程化”:会优先使用激活的 venv,其次使用 CONDA_PREFIX,再去找当前/父目录下的 .venv;找不到会提示你创建。把项目统一成 .venv,配合 uv 的自动发现,能减少很多“装到系统 Python 里”的事故。
七、总结
如果你目前的工作流是 pip + requirements.txt,最小迁移就是把:
- pip install -r requirements.txt
替换为:
- uv pip sync requirements.txt
基本不改变习惯,但能显著改善“解析慢、安装慢、环境不一致”的体验;如果你进一步追求复现与协作效率,再走向 pyproject.toml + uv.lock + uv sync 的项目化工作流。
参考链接
- 官网Github
https://github.com/astral-sh/uv
- 官方文档
https://docs.astral.sh/uv/
https://docs.astral.sh/uv/getting-started/installation/
https://docs.astral.sh/uv/pip/environments/
https://docs.astral.sh/uv/pip/compile/