PDM:下一代 Python 包管理器

Posted by xyx on 2025-09-24
Words 2k and Reading Time 7 Minutes
Viewed Times

PDM:下一代 Python 包管理器

引言

Python Development Master (PDM) 是一款现代化的 Python 包管理器,旨在提供更高效、更灵活的项目依赖管理解决方案。与传统的包管理器(如 Pipenv、Poetry)不同,PDM 基于 PEP 582(Python 本地包目录)提案,不再强制依赖虚拟环境,从而有效避免了虚拟环境嵌套可能引发的冲突和管理复杂性。PDM 的核心优势在于其独特的设计理念和强大的功能集,使其成为 Python 开发者管理项目依赖的有力工具

PDM 的核心特性

PDM 的设计理念聚焦于提升开发者体验和项目管理效率,其主要特性包括:

  • 无需虚拟环境:PDM 创新性地支持 PEP 582 提案,允许项目依赖直接安装在项目根目录下的 __pypackages__ 目录中,从而摆脱了传统虚拟环境的束缚。这简化了环境管理,并使得项目更加自包含和可移植
  • 高效的依赖解析器:PDM 内置了一个简单而快速的依赖解析器,尤其在处理大型二进制包时表现出色,能够迅速计算并锁定所有直接和间接依赖的版本
  • 灵活的插件系统:PDM 提供了强大且可扩展的插件系统,允许用户根据自身需求定制和扩展功能,极大地增强了其灵活性和适应性
  • 兼容 PEP 517 和 PEP 621:PDM 完全兼容 PEP 517 (用于构建发布包,支持源码格式与 wheel 格式) 和 PEP 621 (用于项目元数据格式),确保了与 Python 生态系统的良好集成和标准化
  • 中心化安装缓存:类似于 pnpm,PDM 实现了中心化的安装缓存机制,可以有效节省磁盘空间,避免重复下载相同的包

在这里插入图片描述

PDM 的安装

PDM 的安装方式多样,官方推荐使用 pipx 进行安装,因为 pipx 专为安装和运行命令行应用程序而设计,能够将 PDM 隔离在其自身的虚拟环境中,避免与系统 Python 环境或其他项目产生冲突。PDM 要求 Python 版本为 3.7 或更高

1
pipx install pdm

python pip 直接安装

1
pip install pdm

项目初始化与依赖管理

1. 创建空白项目

通过以下命令可以快速创建一个 PDM 管理的空白项目:

1
2
mkdir my-project && cd my-project
pdm init

pdm init 命令会引导用户完成项目初始化过程,包括选择 Python 解释器、项目名称、版本、许可证、作者信息以及所需的 Python 版本范围等。完成初始化后,项目目录下会生成两个关键文件:

  • .pdm-python:存储用户选择的 Python 解释器路径,供 PDM 后续命令使用。可以通过 pdm use 命令更改
  • pyproject.toml:PDM 的项目配置文件,遵循 PEP 621 标准,记录了项目的元数据和依赖信息

2. 添加、移除和查看依赖

PDM 使用 pdm add 命令来添加项目依赖。例如,为项目添加 ragas 库:

1
pdm add ragas==0.3.5

执行 pdm add 后,PDM 会自动执行以下操作:

  • 将新添加的依赖及其版本信息记录到 pyproject.toml 文件中。
  • 解析所有依赖关系,并生成或更新 pdm.lock 文件。pdm.lock 文件精确锁定了所有直接和间接依赖包的版本,确保了环境的可复现性

若要移除依赖,可以使用 pdm remove 命令:

1
pdm remove ragas

查看已安装依赖的详细信息,可以使用 pdm showpdm list 命令:

1
2
pdm show ragas
pdm list --graph # 以树状形式查看依赖关系

3. 配置 PyPI 源

为了加快包的下载速度,可以配置 PDM 使用国内的 PyPI 镜像源。可以设置全局默认源,也可以添加额外的源:

1
2
3
4
5
# 更改默认源为清华源
pdm config pypi.url "https://pypi.tuna.tsinghua.edu.cn/simple"

# 增加额外的源
pdm config pypi.extra.url "https://pypi.python.org/simple/"

4. 锁定和同步依赖

pdm lock 命令会根据 pyproject.toml 中声明的依赖,解析并生成一个 pdm.lock 文件,确保每次安装的依赖环境都是一致的:

1
pdm lock

pdm sync 命令则会根据 pdm.lock 文件中的精确版本信息,安装或更新项目依赖,确保项目环境与锁文件保持同步。这在团队协作或部署时尤为重要

虚拟环境与 Python 解释器管理

尽管 PDM 的核心特性是无需虚拟环境,但它也提供了对虚拟环境的良好支持,以适应不同开发者的工作流和 IDE 工具的兼容性

1. 创建和使用虚拟环境

PDM 允许用户创建和管理虚拟环境:

1
2
3
4
5
6
7
8
9
10
11
# 查看可用的 Python 解释器
pdm python list

# 创建虚拟环境
pdm venv create -n <venv_name> <python_path>

# 查看已创建的虚拟环境(* 代表当前正在使用的)
pdm venv list

# 选择并激活虚拟环境
pdm use <venv_name>

2. 安装其他 Python 解释器

PDM 支持从 @indygreg’s python-build-standalone 安装其他 Python 解释器,方便开发者管理多个 Python 版本:

1
2
3
4
5
6
7
8
# 查看可下载的 Python 版本列表
pdm python install --list

# 下载指定版本的 Python (例如 CPython 3.9.12)
pdm python install 3.9.12

# 查看当前 PDM 项目使用的 Python 版本
pdm run python --version

3. 优化依赖解析速度

在执行 pdm installpdm lock 命令时,如果遇到依赖解析耗时过长的情况,可以通过在 pyproject.toml 文件中精确指定 Python 版本范围来优化速度,例如:

1
2
[project]
requires-python = ">=3.9,<3.10"

运行命令与脚本别名

PDM 提供了 pdm run 命令来在项目环境中执行脚本或命令。为了简化复杂命令的执行,可以在 pyproject.toml 中配置命令别名:

1
2
3
4
5
6
7
8
9
10
[tool.pdm.scripts]
start = "python main.py"

# 或者使用更详细的配置,支持注释和环境变量
[tool.pdm.scripts]
start = {cmd = [
"flask",
"run",
"-p", "54321" # Important comment here about always using port 54321
], env_file = ".env"}

配置别名后,可以直接通过 pdm run start 来执行对应的命令

方案兼容

PDM 足够好用,也足够开放,如果你当前使用的是其他的包管理器,比如 pipenv,poetry,requirements.txt ,你也可以很方便的迁移到 pdm 中来,下面以导入导出 requirements为例

1
2
3
4
5
# 从已有的requirements.txt文件导入
pdm import -f requirements requirements.txt

# pdm 导出requirements.txt文件
pdm export -o requirements.txt

总结

  • 优点: PDM 作为一款现代 Python 包管理器,凭借其无需虚拟环境、高效依赖解析、灵活插件系统以及对新 PEP 标准的良好支持,为 Python 项目管理带来了全新的体验。它不仅解决了传统包管理器在虚拟环境嵌套等场景下的痛点,还通过中心化缓存等机制提升了开发效率。无论是个人项目还是团队协作,PDM 都提供了一个强大而便捷的解决方案
  • 缺点: 执行pdm addpdm lock等操作时,因为要解析包或子包的依赖关系,会导致下载时耗时很长,在非常明确要添加的版本号和依赖关系的时候,其实是不如用pip install命令更敏捷

参考文献