Python 依赖管理与打包:从 pip 到 uv 的进化史h1
在 Python 项目里,依赖管理常常是最容易踩坑、但又最容易被忽略的一环。从最原始的 pip install 一路走到现代化工具 uv、poetry,整个生态正在快速迭代。本文尝试从一个学习者的视角,把“为什么需要它们、它们是如何解决问题的”梳理清楚,让你用起来不再迷糊。
1. pip 与全局环境的问题h2
当我们运行:
pip install ABC所有依赖都会进入 全局环境,导致:
- 不同项目依赖版本冲突
- 项目之间互相污染依赖
于是我们需要虚拟环境。
2. venv:解决“项目之间的污染”h2
python -m venv .venvsource .venv/bin/activate独立环境解决了冲突,但带来新的问题——依赖如何被记录?
3. requirements.txt:能用,但不够优雅h2
pip freeze > requirements.txt但卸载 ABC 后,其间接依赖 EDF 仍留在 freeze 结果中。
缺点:
- 不能区分 direct vs indirect 依赖
- 文件越来越脏
4. pyproject.toml:记录“直接依赖”h2
[project]dependencies = [ "ABC",]优点:只记录 direct dependencies。
但:
- 项目需要通过
pip install -e .才能正常开发 - pip install . 既会打包又会安装
流程仍然复杂。
5. pip + venv + pyproject 的完整流程h2
python -m venv .venvsource .venv/bin/activate# 编辑 pyproject.tomlpip install -e .协作时还需要:
pip install -r requirements.txt体验仍不够丝滑。
6. uv:现代化依赖管理工具h2
可以把 uv 理解为对 pip + venv 的高级封装。
新增依赖:
uv add ABCuv 会自动处理:
- 创建虚拟环境
- 安装依赖
- 修改 pyproject.toml
- 写入 direct dependencies
- 同步间接依赖
协作者同步依赖:
uv sync运行脚本:
uv run test.py更丝滑的 Python 体验。
7. 安装不同 Python 版本h2
uv python install cpython-3.13uv run -p 3.13 test.pyuv init -p 3.13无需外部管理器。
8. 查看依赖树h2
uv tree9. 工具依赖 vs dev 依赖(以 Ruff 为例)h2
uv add ruff --dev但由于 Ruff 是工具,更推荐:
uv remove ruff --devuv tool install ruff避免污染项目依赖。
10. 项目打包:scripts + uv buildh2
[project.scripts]commandname = "scriptname:functionname"构建:
uv build会生成 .whl 文件(本质是 zip)。
FAQ:commandname 的依赖来自哪里?它有自己的 venv 吗?h2
✔ 1. commandname 运行在“安装它的环境”里h3
- 若通过
uv add安装 → 使用项目 .venv - 若通过
uv tool install安装 → uv 为其创建独立沙盒环境
✔ 2. whl 并不会把所有依赖“物理打包”进去h3
它只记录 direct dependencies。
✔ 3. uv tool install 会自动创建隔离环境h3
这是 uv 的核心优势之一。
总结:为什么最终选择 uv?h2
因为它把原本四步的流程变成:
uv add ABCuv syncuv run test.pyuv build现代化、清晰、高效。