Appearance
Python 包管理工具
环境搭建 一章已经介绍了 pip 的基本用法和镜像源配置。但 Python 生态里远不止 pip 一种工具——随着项目复杂度上升,依赖锁定、项目管理、版本管理、工具运行 等需求会让单一 pip 显得力不从心。本章把主流的 Python 包管理工具逐一梳理,分别说明其定位、用法与优缺点,并在末尾给出选型建议。
先厘清几个概念
在比较工具之前,先统一几个常被混淆的术语:
- 包安装(package install):把 PyPI 上的包下载并安装到某个环境。代表:pip。
- 依赖锁定(dependency locking):把整个依赖树(含间接依赖)解析成一个可复现的锁文件。代表:pip-tools、poetry、uv。
- 项目管理(project management):基于
pyproject.toml管理项目元数据、依赖、构建、发布。代表:poetry、pdm、uv。 - 环境管理(environment management):创建隔离的虚拟环境。代表:venv、virtualenv、conda、uv。
- Python 版本管理(interpreter management):安装并切换多个 Python 解释器。代表:pyenv、conda、uv。
很多工具同时覆盖多项能力,这正是选型时容易混乱的原因。下文每个工具都会点明它覆盖了哪些范围。
pip
定位
pip 是 Python 官方的包安装工具,几乎所有 CPython 发行版都自带。它只解决「包安装」这一件事,不负责锁定、不负责项目管理、不负责环境隔离。
基本用法
bash
pip install requests # 安装包
pip install "requests>=2.31" # 指定版本约束
pip install -r requirements.txt # 从 requirements 文件安装
pip install -e . # 可编辑安装当前项目
pip uninstall requests # 卸载
pip list # 列出已安装包
pip freeze > requirements.txt # 导出当前环境的包(非锁文件)
pip install --upgrade pip # 升级 pip 自身镜像源配置见 环境搭建 一章的「配置国内镜像源」小节。
优点
- 官方标准:随 Python 附带,无需额外安装,生态最广。
- 接口简单:
install / uninstall / list / freeze四条命令覆盖绝大多数场景。 - 兼容性最好:所有 CI、Docker 镜像、教程默认都用 pip,迁移成本为零。
- PEP 508 依赖规范完整支持。
缺点
- 无锁文件:
pip freeze只是「当前环境快照」,不是可复现的依赖解析结果,间接依赖的版本无法精确控制。 - 依赖解析慢且偶尔出错:早期版本在复杂依赖图下可能给出不可行的解,新版回溯解析器有所改善但仍偏慢。
- 不管理项目结构:没有
pyproject.toml项目概念,元数据要手写或借助setuptools。 - 不管理虚拟环境和 Python 版本:需要配合
venv、pyenv使用。 - 不支持工作区/monorepo。
适用场景
- 临时脚本、学习用的小项目。
- 从
requirements.txt安装依赖的 CI 流水线。 - 作为其他工具的底层接口(很多工具底层仍调用 pip 或复用其索引协议)。
pip-tools
定位
pip-tools 在 pip 之上补齐了「依赖锁定」能力,由两套命令组成:pip-compile(生成锁文件)和 pip-sync(按锁文件精确同步环境)。它不引入新的项目结构,是对 requirements 工作流的轻量增强。
基本用法
bash
pip install pip-tools
# 写一份粗粒度的依赖清单
echo "requests>=2.31" > requirements.in
echo "flask" >> requirements.in
# 解析整棵依赖树,生成带版本的 requirements.txt(锁文件)
pip-compile requirements.in -o requirements.txt
# 按锁文件精确同步环境(多余包会被卸载)
pip-sync requirements.txt
# 升级某个包到允许范围内的最新版
pip-compile --upgrade-package requests优点
- 轻量无侵入:不改项目结构,不要求
pyproject.toml,旧项目可零成本接入。 - 锁定精确:
pip-compile输出含哈希的锁文件,可复现、可校验。 - 与 pip 完全兼容:输出的
requirements.txt可直接交给 pip 在 CI 中使用。 - 学习曲线极低:两条命令即可上手。
缺点
- 只解决锁定:不管理项目元数据、构建、发布、环境、Python 版本。
- 仍需手动配合 venv:环境隔离要自己建。
- 没有项目级依赖声明:
requirements.in是纯文本,无法表达 extras、可选依赖分组等结构化信息(表达能力弱于pyproject.toml)。 - 速度与 pip 相当:底层仍走 pip 解析器。
适用场景
- 旧项目想引入「可复现依赖」但不想上重型工具。
- Django/Flask 等传统 Web 项目,依赖结构相对简单。
conda
定位
conda 是一个跨语言的包和环境管理器,最初为科学计算社区(Anaconda 公司)打造。它的包仓库(Anaconda Repository / conda-forge)里有大量预编译的二进制包,包括非 Python 的 C/Fortran 库(如 NumPy 的 BLAS、CUDA 工具链、R 语言等)。
基本用法
bash
# 安装 Miniconda(精简版,推荐)或 Anaconda(全家桶)
# 创建环境并指定 Python 版本
conda create -n myenv python=3.12
conda activate myenv
# 安装包(来自 conda-forge 频道)
conda install -c conda-forge numpy pandas scipy
# 混用 pip:conda 环境里也能跑 pip
pip install requests
# 导出与复现环境
conda env export --from-history -f environment.yml
conda env create -f environment.yml优点
- 能装非 Python 依赖:这是 conda 最大的差异化能力。数据科学里常见的 CUDA、GDAL、ffmpeg 等二进制库,用 conda 一条命令搞定,而 pip 装不上或要本地编译。
- 环境与解释器一体化:
conda create同时指定 Python 版本和包,无需 pyenv + venv 拼装。 - 预编译二进制:避免源码编译失败,对 Windows 和 M 系列 Mac 友好。
- conda-forge 社区活跃:覆盖面极广。
缺点
- 慢:依赖解析器历史上很慢(mamba/micromamba 是它的 C++ 重写版,速度快很多)。
- 体积大:Anaconda 全家桶数 GB;Miniconda 也有几百 MB。
- 与 PyPI 生态重叠且不完全兼容:同一个包在 conda 和 pip 里都可能存在,混装易导致环境损坏。
- 不擅长项目管理:没有
pyproject.toml锁文件概念,environment.yml表达力弱。 - 许可证:Anaconda 商业使用有额外条款(2020 年起对 200 人以上组织商用收费),Miniconda 与 conda-forge 不受此限。
适用场景
- 数据科学、机器学习、科学计算(PyTorch、TensorFlow、地理信息、生物信息)。
- 需要管理非 Python 二进制依赖的项目。
- 不适合:纯 Web 后端、CLI 工具等以 PyPI 为主的项目,用 conda 反而徒增负担。
Poetry
定位
Poetry 是最早成熟的现代化 Python 项目管理工具之一。它围绕 pyproject.toml 统一管理依赖、锁文件(poetry.lock)、虚拟环境、构建与发布,目标是「一个工具搞定项目全生命周期」。
基本用法
bash
pip install poetry # 或用官方安装脚本
poetry --version
poetry new my-pkg # 创建包项目
poetry init # 在已有目录初始化
poetry add requests # 添加依赖
poetry add --group dev pytest # 添加到开发依赖组
poetry remove requests # 移除
poetry install # 按 lock 安装(含开发依赖)
poetry update # 更新依赖并刷新 lock
poetry lock # 仅刷新锁文件
poetry run python main.py # 在项目环境中运行
poetry shell # 激活虚拟环境
poetry build # 构建 sdist + wheel
poetry publish # 发布到 PyPI优点
- 生态成熟:社区大、文档全、第三方插件多,是目前最常见的项目工具之一。
- 全生命周期覆盖:依赖、锁文件、环境、构建、发布一站式。
- 依赖解析较稳健:自带解析器,锁文件可复现。
- 开发依赖分组:
--group支持多组可选依赖,CI 里可按需安装。
缺点
- 配置非完全标准:早期依赖
[tool.poetry]自有段而非 PEP 621 标准[project]段(1.8+ 已支持 PEP 621,但迁移仍在进行)。 - 速度一般:纯 Python 实现,安装与解析速度与 pip 相当,对大型项目偏慢。
- 不管理 Python 版本:仍需 pyenv 等配合。
- 环境管理封闭:默认把虚拟环境放在统一目录,而非项目
.venv,需配置virtualenvs.in-project才贴近习惯。 - monorepo 支持弱:没有原生工作区概念。
- 打包用自有后端:与 PEP 517 标准后端有差异,少数边缘场景兼容性需注意。
适用场景
- 中大型应用项目,希望「一个工具管全部」。
- 团队已有 Poetry 沉淀,优先沿用。
- 库项目需要规范的构建发布流程。
PDM
定位
PDM(Python Development Master)是一个严格遵循 PEP 标准的现代项目管理工具,支持 PEP 517(构建)、PEP 582(无虚拟环境的 __pypackages__)、PEP 621(项目元数据)。它主打「标准先行」。
基本用法
bash
pip install pdm
pdm --version
pdm init # 初始化项目(交互式)
pdm add requests # 添加依赖
pdm add -dG test pytest # 添加到 test 可选组
pdm remove requests
pdm install # 按 lock 安装
pdm update
pdm lock
pdm run python main.py # 运行
pdm run pytest
pdm build # 构建
pdm publish # 发布优点
- 严格遵循 PEP 标准:原生 PEP 621
[project]段,配置即标准,迁移成本低。 - 支持 PEP 582:可不建虚拟环境,直接用
__pypackages__,对部分场景更轻。 - 支持工作区/monorepo:原生多包项目支持。
- 可引导安装:PDM 能自己管理 Python 解释器(基于 python-build-standalone),功能接近 pyenv。
- 解析器较快:采用
unearth+resolvelib,比传统 pip 解析有改善。
缺点
- 生态规模不及 Poetry:社区和插件较少,第三方集成(IDE、CI 模板)相对薄弱。
- 速度仍不及 uv:纯 Python 实现,与 pip 同量级。
- PEP 582 非主流:虽然标准存在,但大多数工具链仍假设虚拟环境,开启
__pypackages__偶有兼容问题。 - 文档与示例不如 Poetry 丰富。
适用场景
- 偏好「标准先行」、注重规范化的团队。
- monorepo 结构的 Python 项目。
- 希望工具同时管理解释器版本,但不想用 uv 的场景。
uv
定位
uv 由 Astral 公司(Ruff 的作者)用 Rust 编写,目标是用单一二进制统一替代 pip、pip-tools、pipx、poetry、pdm、pyenv、virtualenv。它在保持与标准兼容的前提下,把性能做到 10-100 倍于 pip。
基本用法
bash
# 安装
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux
# Windows: irm https://astral.sh/uv/install.ps1 | iex
# Python 版本管理(替代 pyenv)
uv python install 3.12
uv python pin 3.12
# 项目管理(替代 poetry/pdm)
uv init my-project
uv add requests
uv add --dev pytest
uv sync # 按 uv.lock 安装
uv run python main.py # 运行(自动同步环境)
uv build && uv publish # 构建发布
# pip 兼容接口(替代 pip/pip-tools,渐进迁移)
uv pip install requests
uv pip compile requirements.in -o requirements.txt
uv pip sync requirements.txt
# 工具运行(替代 pipx)
uvx ruff check . # 一次性运行
uv tool install httpie # 全局安装 CLI优点
- 极快:Rust 实现 + 全局缓存 + 并行下载,安装速度比 pip 快一到两个数量级,大型项目依赖安装从分钟级降到秒级。
- 一站式:一个二进制覆盖版本管理、环境、项目、锁定、工具运行、构建发布。
- 标准遵循:原生 PEP 621,
pyproject.toml与uv.lock与生态兼容。 - 兼容 pip 接口:
uv pip子命令与 pip/pip-tools 一致,旧项目可零成本切换享受加速。 - 管理 Python 解释器:内置下载托管版 Python,不再需要 pyenv。
- 跨平台单二进制:Windows/macOS/Linux 体验一致,CI 与 Docker 友好。
- 工作区支持:原生 monorepo 能力。
缺点
- 相对年轻:1.0 于 2024 年发布,部分边缘场景仍在打磨,偶尔遇到边界问题。
- 单一公司主导:长期可持续性取决于 Astral(同 Ruff),社区治理尚在演进。
- 不管理非 Python 依赖:不像 conda 能装 CUDA、BLAS 等系统级二进制库,数据科学重度场景仍需 conda 配合。
- 生态尚在追赶:插件与第三方集成不如 Poetry 丰富。
- 行为默认值激进:自动同步、自动建
.venv等约定对从 pip 迁移的用户需要适应。
适用场景
- 新项目首选:应用、库、CLI 工具均适用。
- 追求构建速度与 CI 时效的中大型团队。
- 想用一套工具替代 pip + pyenv + venv + poetry + pipx 的开发者。
- 不适合:强依赖非 Python 二进制库的科学计算项目(与 conda 互补而非替代)。
uv 更详细的命令速查见备忘录 uv。
pipx
定位
pipx 专门用于「全局安装并隔离运行 Python 写的 CLI 工具」,例如 black、ruff、httpie、ansible。每个工具装在独立虚拟环境里,但把可执行文件暴露到 PATH,避免污染系统 Python。
基本用法
bash
pip install pipx
pipx ensurepath
pipx install black # 全局安装
pipx install --force black # 强制重装
pipx list # 查看已装工具
pipx upgrade black # 升级
pipx upgrade --all
pipx uninstall black
pipx run pycowsay hello # 临时运行(不安装)优点
- 隔离干净:每个 CLI 独立环境,互不冲突,系统 Python 不被污染。
- 比
pip install --user安全:避免工具间依赖打架。 pipx run一次性执行:类似npx,适合临时用某个工具。- 注入额外包:
pipx inject <app> <pkg>可往某工具环境补包。
缺点
- 只面向 CLI 工具:不管理库项目、不管理应用依赖。
- 底层仍用 pip + venv:速度无提升。
- 已被 uv 内置能力覆盖:
uv tool/uvx提供等价功能且更快,新项目可不必单独装 pipx。
适用场景
- 仍用 pip/poetry 工作流的团队,需要一个干净的 CLI 工具安装器。
- 已迁移到 uv 的项目,可直接用
uv tool/uvx替代,无需 pipx。
工具能力对比总览
| 能力 / 工具 | pip | pip-tools | conda | poetry | pdm | uv | pipx |
|---|---|---|---|---|---|---|---|
| 安装包 | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ⚠️ CLI |
| 依赖锁定 | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
| 项目管理 | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ |
| 虚拟环境管理 | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Python 版本管理 | ❌ | ❌ | ✅ | ❌ | ⚠️ | ✅ | ❌ |
| CLI 工具运行 | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| 打包发布 | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ |
| 工作区 / monorepo | ❌ | ❌ | ❌ | ⚠️ 弱 | ✅ | ✅ | ❌ |
| 非 Python 二进制 | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| 速度(相对 pip) | 1× | ~1× | 慢 | ~1× | ~1× | 10-100× | ~1× |
| 实现语言 | Python | Python | C/Py | Python | Python | Rust | Python |
| PEP 621 标准 | ⚠️ | ❌ | ❌ | ⚠️ | ✅ | ✅ | ❌ |
如何选择
选型没有银弹,关键是匹配项目特征:
- 学习用、临时脚本 → pip +
venv足矣,不要过度工具化。 - 传统 Web 项目(Django/Flask),只需可复现依赖 → pip-tools,轻量、零侵入。
- 数据科学 / 机器学习 / 需要非 Python 二进制依赖 → conda(或更快的 micromamba),必要时与 pip 混用。
- 中大型应用或库项目,想要全生命周期管理:
- 新项目 → uv(性能与一体化最优)。
- 已有 Poetry 沉淀 → 继续 Poetry,迁移成本不划算时不必折腾。
- 偏好标准先行、有 monorepo 需求 → PDM 或 uv。
- 全局安装 CLI 工具 → uv tool / uvx(新项目)或 pipx(存量项目)。
一个常见的现代组合是:uv 管项目与日常开发,遇到必须装 CUDA/BLAS 等二进制依赖时用 conda 补充。两者并非互斥,conda 提供 Python 解释器与系统库,uv 在其环境内做项目管理,是当前数据工程团队较流行的搭配。
相关阅读
- 环境搭建:pip 安装与镜像源配置的入门内容。
- Python 升级指南:解释器版本升级的跨平台做法。
- 项目打包与部署:构建与发布的进一步实践。
- 备忘录 uv:uv 命令速查与镜像源配置。
总结
Python 包管理工具呈现「分层演进」的格局:pip 是底座,pip-tools 是对底座的轻量增强,conda 走跨语言二进制路线,poetry/pdm 把项目管理做厚,uv 则用 Rust 把整条工具链重写并整合。理解每个工具覆盖的能力范围(安装 / 锁定 / 项目 / 环境 / 版本 / 工具运行 / 二进制),比记住命令更重要——选型本质上是按项目需要的能力组合去匹配工具。掌握本章后,你应能为不同项目挑出合适的工具组合,并在团队中给出有依据的选型建议。