从 venv 到 uv:一次 Python 环境管理的迁移实践
带的项目多了以后,最头疼的不是写代码,而是环境。同一台机器上 Python 3.9 到 3.12 共存,每个项目一个 venv,装依赖时 pip 在国内网络环境下经常超时;requirements.txt 只锁版本号不锁哈希,换台机器装出来的依赖树就不一样了。这些问题单独看都能忍,凑在一起就想换个方案。
uv 是 Astral(做 Ruff 的那家)用 Rust 写的 Python 包和环境管理器,2024 年初开源,迭代很快。它把 pyenv、venv、pip、pip-tools、pipx 的活全干了,解析和安装依赖的速度比 pip 快一个量级。
安装
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 能打印版本号就可以用了。
常用命令对照
| 原来 | 现在 |
|---|---|
| python -m venv .venv | uv venv |
| pip install requests | uv pip install requests |
| pip install -r requirements.txt | uv pip install -r requirements.txt |
| pip freeze > requirements.txt | uv pip freeze |
| pyenv install 3.12 | uv python install 3.12 |
| pipx install black | uv tool install black |
uv venv 默认使用 uv 自己托管的 Python,也可以用 uv venv --python 3.12 指定版本。第一次用到某个版本时它会自动下载,不用再单独装 pyenv。
真正的好处:项目化管理
上面这些用法只是"更快的 pip"。uv 真正的价值在 uv init / uv add 这套项目工作流:
uv init myproj && cd myproj
uv add requests
uv add --dev pytest
uv run python main.py
几点感受:
- 依赖写进 pyproject.toml,不用再手工维护 requirements.txt
- 自动生成 uv.lock,精确锁到哈希,任何机器上
uv sync装出来的环境完全一致 uv run会自动使用项目虚拟环境,日常不用再手动 activate
迁移老项目
老项目一般只有一份 requirements.txt,两种迁法:
- 保守迁法:继续
uv pip install -r requirements.txt,只享受速度提升,流程完全不变; - 彻底迁法:在项目里
uv init之后uv add -r requirements.txt,让 uv 生成 pyproject.toml 和 uv.lock,之后统一用uv run/uv sync。
我的做法是新项目直接上项目化工作流,老项目等下一次大改动时顺手迁。
踩过的坑
- 旧 VIRTUAL_ENV 残留:从 venv 切过来时如果终端里还导出着旧的 VIRTUAL_ENV,uv 的行为会很怪,新开一个终端就好;
- Windows 长路径:个别包安装时路径超长会报错,注册表开启 LongPathsEnabled 可以解决;
- IDE 解释器:VS Code / PyCharm 要记得手动把解释器指到项目的 .venv,uv 不会帮你改 IDE 配置;
- 私有源:公司内有 PyPI 镜像时,配 UV_INDEX_URL 环境变量,或在 pyproject.toml 里加
[[tool.uv.index]]配置。
小结
工具不能解决所有问题,但能把重复劳动压缩掉。迁移两周下来,新项目从初始化到跑通 CI 的时间明显缩短,lockfile 带来的确定性也让"我本地是好的"这种对话少了很多。如果你还在被多版本 Python 和慢 pip 折磨,值得一试。
- 点赞
- 收藏
- 关注作者
评论(0)