sync 与 pip 工作流全对比
最近把团队的 Python 依赖管理从 pip 迁到了 uv,速度快得离谱,但有个问题一直有人问:
“uv sync和uv venv && source .venv/bin/activate && uv pip install -r requirements.txt不都是装依赖吗?有啥区别?”
表面看都是“建环境 + 装包”,但底层是两套完全不同的工作流范式。一个走 uv 的项目管理(声明式)路线,一个走兼容 pip(命令式)路线。搞混了,就会遇到“在我机器上是好的”这类经典事故。
这篇文章把二者的差异一次讲清楚,并给出选型建议。
一、两条命令长什么样
命令 A —— uv 的项目工作流:
uv sync命令 B —— uv 的 pip 兼容工作流:
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt就差这几个字,行为却天差地别。
二、一句话本质区别
uv sync 是声明式的:你声明“我需要什么”,uv 负责把环境对齐成那个样子,多退少补。uv pip install 是命令式的:你下一条指令,它就执行一条,只管往上堆,不管环境现状。
三、五大核心差异
1. 依赖信息从哪读
uv sync:读取pyproject.toml(声明依赖)+uv.lock(锁定版本),优先按 lock 精确还原。uv pip install -r:只读requirements.txt,完全不认识pyproject.toml。里面是范围约束还是精确版本,全看你自己的写法。
2. 可复现性
uv sync:因为有uv.lock,团队和不同机器装出来的版本完全一致,这是它最大的卖点。uv pip install -r:如果requirements.txt没锁死版本(比如写着requests>=2.0),每次可能拉到不同的新版,环境悄悄漂移。
3. 环境状态管理
uv sync:把环境对齐成“恰好等于声明的依赖集合”,多出来的包(extraneous)会自动清理,环境始终干净。uv pip install:累加式,只往里装,不会帮你删掉手抖多装的包。
4. 是否安装“你自己的项目”
uv sync:默认把当前项目本身以可编辑模式(editable)一起装进.venv,本地开发直接import自己。uv pip install -r:只装requirements.txt里的东西,不碰项目本身(除非你把-e .写进 requirements)。
5. 需不需要激活虚拟环境
uv sync:不需要source激活。uv 自动管理.venv,直接uv run python/uv run xxx就能用对的环境。uv pip install:需要先激活 venv(或显式uv pip install --python .venv/bin/python),否则可能装到别的环境去。
四、对照表
| 维度 | uv sync | uv venv && activate && uv pip install -r |
|---|---|---|
| 依赖来源 | pyproject.toml + uv.lock | requirements.txt |
| 可复现 | ✅ 强(lock 锁版本) | ⚠️ 取决于 requirements 是否锁定 |
| 环境清理 | ✅ 自动移除多余包 | ❌ 只增不减 |
| 安装本项目 | ✅ 默认 editable | ❌ 不装 |
| 需要激活 | ❌ 不需要 | ✅ 需要(或指定 --python) |
| 典型定位 | 项目开发 / 协作首选 | 兼容旧 pip 习惯、复用已有 requirements |
五、怎么选型
- 新项目 / 要协作 / 要可复现 → 用
uv sync,配合uv add管理依赖,把uv.lock提交进版本库。 - 只是想拿 uv 当“更快的 pip”、手头只有
requirements.txt→ 用后者也行,但强烈建议用uv pip compile把requirements.txt锁成精确版本,避免漂移。
六、从 requirements.txt 迁移到 uv sync 的建议
如果你现在还是 requirements.txt 那一套,迁移成本很低:
# 1. 初始化 pyproject.toml(如果还没有)
uv init
# 2. 把 requirements 里的依赖加进项目
uv add -r requirements.txt
# 3. 之后统一用 sync 还原环境
uv sync从此团队里每个人、每次 CI,装的都是一模一样的版本。
结语
uv sync 和 uv pip install 不是“新旧替换”的关系,而是两种心智模型:一个是“我要环境长成什么样”,一个是“我要装哪个包”。新手建议直接上 uv sync,把可复现性交给 lock 文件;老项目想渐进迁移,先用 uv pip compile 锁版本,再慢慢搬进 pyproject.toml。
用对了工作流,能省掉一半“在我机器上是好的”式扯皮。
评论
发表评论