当前位置:首页>python>从 pip 乱装到 uv 统管:一个 Python 开发者的包管理血泪史

从 pip 乱装到 uv 统管:一个 Python 开发者的包管理血泪史

  • 2026-09-10 10:42:41
从 pip 乱装到 uv 统管:一个 Python 开发者的包管理血泪史

从 pip 乱装到 uv 统管:一个 Python 开发者的包管理血泪史

我第一次用 Python 的时候,完全不知道什么叫"环境管理"。

pip install numpy,装好了。pip install pandas,装好了。pip install flask,也装好了。感觉一切都很美好,直到某天运行一个旧项目,报错说某个包版本不对,改了版本又把另一个项目搞崩了——两个项目死活不能同时好用。

那时候我就在想:Maven 不是这样的,pnpm 也不是这样的,为什么 Python 这么难用?

◆ ◆ ◆

第一关:全局污染

刚学 Python 的人几乎都会犯同一个错误:直接 pip install,往全局环境装包。

这没什么问题,直到你同时维护多个项目。

项目 A 需要 requests 2.28,项目 B 需要 requests 2.31,全局只能装一个版本,装了新的旧项目报错,装了旧的新项目报错。版本依赖冲突这个坑,几乎每个 Python 新手都会踩。

不只是项目之间,工具之间也会打架。black、ruff、poetry 这些开发工具,底层也依赖各种包,全装在同一个全局环境里,版本一冲突,有时候工具自己就运行不了。

Java 用 Maven,每个项目有自己的 pom.xml,依赖隔离。Node.js 用 npm/pnpm,node_modules 在项目目录里,互不干扰。 为什么 Python 要这么搞?

其实 Python 也有解决方案,只是很多人不知道——那就是 venv。

◆ ◆ ◆

第二关:venv 解决了项目冲突,工具还是一锅粥

python -m venv .venv 一行命令,在项目目录下创建一个独立的 Python 环境。每个项目用自己的 venv,包版本互相隔离,项目之间的冲突问题基本解决了。

但工具类的问题还没完全解决。black、ruff 这些开发工具,你还是得往某个环境里装,装在全局里又回到了冲突的老路,装在每个项目的 venv 里又嫌麻烦——每个项目都要装一遍,而且工具本来是"给人用的",不该绑死在某个项目里。

这时候 pipx 出现了,思路很巧:给每个命令行工具单独创建一个隔离的 venv,工具在自己的小房间里互不打扰,同时把可执行文件注册到系统 PATH,终端里直接调用。

工具之间的包冲突就这样解决了。

直到开始做 AI 开发,新的问题来了。

◆ ◆ ◆

第三关:每个环境都要重复下载 torch,硬盘告急

第一次在项目里装 PyTorch,等了十几分钟,2.几个 GB 下载完,pip install 完成。

第二个 AI 项目,再装 PyTorch,又等了十几分钟。

第三个、第四个……每个 venv 都要单独装一次 PyTorch,每次都是近 3G 的包,每个 venv 占十几个 G,硬盘很快就见底了。

pipx 的隔离 venv 解决了工具冲突,但本质上还是"每个环境各自存一份包"。项目 venv 是这样,pipx 的工具 venv 也是这样,同样的文件在硬盘上存了十几份,没有任何复用。

做 AI 开发的人应该都经历过这种痛苦:光是 torch + torchvision + torchaudio,一套下来就要 35G,10 个项目就是 3050G 白白浪费在重复的文件上。

◆ ◆ ◆

终局:uv 才是真正的答案

后来接触到 uv,用了之后就再也回不去了。

uv 是用 Rust 写的 Python 包管理工具,速度极快(比 pip 快 10~100 倍),但速度还不是它最让我惊喜的地方。

真正让我眼前一亮的是它的全局缓存 + 硬链接机制。

装过一次的包,下次再装直接从缓存里读,不下载、不复制,而是用硬链接。硬链接意味着同一份文件在文件系统里被多个位置"共享引用",不占额外空间。

十个项目都用 torch?全局缓存里只有一份 torch,10 个项目的 venv 里都通过硬链接指向同一份文件,磁盘占用从 30G 变成 3G。

这才是我一直想要的,和 pnpm 的 store 机制一模一样的思路。而且 uv 把 venv、工具管理、Python 版本管理全部统一进来了,不再需要 venv + pipx 两套工具拼凑。

◆ ◆ ◆

uv 的使用方式

第一步:安装 uv

uv 本身是独立的 Rust 二进制,不依赖系统已有的 Python 或 pip,直接一行安装:

# Windows PowerShellirm https://astral.sh/uv/install.ps1 | iex# macOS / Linuxcurl -LsSf https://astral.sh/uv/install.sh | sh

装完验证一下:uv --version,出现版本号就好了。

第二步:用 uv 管理 Python 版本

以前装多个 Python 版本,要么去官网手动下载,要么用 pyenv(Windows 上还不太好用)。uv 直接内置了 Python 版本管理:

# 安装指定版本uv python install 3.11uv python install 3.12# 查看所有已安装版本uv python list

系统里不需要提前装任何 Python,uv 自己全管了。

第三步:创建项目环境

# 创建虚拟环境(默认用已有 Python,没有会自动下载)uv venv# 指定版本uv venv --python 3.11# 安装依赖uv add torch numpy pandas# 从 requirements.txt 安装uv pip install -r requirements.txt

‣ 不需要手动激活 venv

原生 venv 最繁琐的一步就是每次都要 source .venv/bin/activate 或者 Windows 下执行激活脚本,忘了就报"找不到包"。

uv 的所有命令会自动检测当前目录下的 .venv,不需要手动激活:

# 直接运行,uv 自动找到并使用 .venvuv run python main.pyuv run pytestuv run jupyter notebook

当然你也可以手动激活,进入激活状态后 python、pip 等命令也照常工作,和原生 venv 完全兼容。

uv tool:统一管理全局工具

uv tool 是内置的工具管理功能,完全替代 pipx,同样是隔离 venv 安装,同样全局可调用,但共享 uv 的全局缓存:

# 安装工具(最新版)uv tool install blackuv tool install ruff# 安装指定版本uv tool install "ruff>=0.3,<0.4"# 查看已安装的工具uv tool list# 升级uv tool upgrade ruffuv tool upgrade --all

安装了某个工具之后,如果某次需要临时用一个不同版本,可以用 @ 语法指定,不会影响已安装的版本:

# 用已安装的版本ruff check .# 临时用特定版本运行(不影响已安装版本)uvx ruff@0.3.0 check .uvx ruff@latest check .

uvx:临时运行,用完即走

uvx 是 uv tool run 的简写,不需要提前安装工具,直接运行,非常适合偶尔用一次的场景:

uvx black .           # 临时跑一次 blackuvx ruff check .      # 临时跑一次 ruffuvx pytest            # 临时跑测试

如果包名和命令名不一样,用 --from 指定:

uvx --from httpie http GET https://example.com

◆ ◆ ◆

一点感慨

用 Python 这几年,包管理的演进路径大概是这样的:

pip 全局安装 → 版本冲突 → 发现 venv,项目隔离了 → 工具还是互相污染 → 发现 pipx,工具也隔离了 → 开始 AI 开发,每个 venv 重复存 torch,硬盘告急 → 发现 uv,全局缓存硬链接,终于和 maven/pnpm 一样舒服了

中间走了很多弯路。其实如果一开始就用 uv,很多坑根本不用踩——从一开始就安装 uv,让 uv 来管 Python 版本,创建项目 venv,安装管理工具,全部由一个工具统管,干净利落。

如果你还在用原生 pip,或者正在为 torch 重复下载烦恼,建议现在就去试试 uv。

◆ ◆ ◆

uv 官方文档:https://docs.astral.sh/uv

次条附 uv 速查表,收藏备用。

最新文章

随机文章