pdm:类Nodejs的python包管理模式
PDM是一款国人开发的类似pip、conda的python包管理器,允许将一个python项目所需的包都放在当前目录下,支持创建多种虚拟环境,也允许自定义命令。其开发受到Node.js包管理器 pnpm
的影响
PDM可基于同一个python解释器构建多个虚拟环境,因此比conda更轻量,比pip更灵活。本文我们了解pdm的基本用法
初始化
安装pdm推荐使用pipx,这是一个python命令行工具安装器。pdm会被安装在 /home/username/.local/bin
目录下
sudo apt install pipx
pipx install pdm
pipx ensurepath
使用 pdm init
命令初始化当前python项目,会列出当前能找到的所有python解释器。如果你同时使用了conda,无法检测到其他conda环境下的python。选择python版本后,其他选项保持默认即可
初始化的目录结构形如
├── .gitignore
├── .pdm-python
├── .venv
│ ├── .gitignore
│ ├── bin
│ ├── lib
│ └── pyvenv.cfg
├── README.md
├── __pycache__
├── pyproject.toml
├── src
│ └── tplot
└── tests
├── __init__.py
└── __pycache__
pyproject.toml
包含项目的构建元数据、项目的依赖环境,也可在此定义快捷命令,类似JavaScript的 package.json
pdm.lock
存储了详细的包版本,类似JavaScript的 package-lock.json, yarn.lock, package-lock.json
等
.venv
存储了虚拟环境,类似JavaScript的 node_modules
.pdm-python
存储当前项目使用的python路径
项目的所有代码写在 src/projname
下,测试文件写在 tests
下
依赖管理
可为项目添加各种依赖项,add
命令会在修改 pyproject.toml
的同时安装好需要的包
# 添加依赖项
pdm add pandas seaborn
# 加入本地包,注意路径必须以./开头
pdm add ./sub-package
# 添加仅开发时的依赖项
pdm add -dG test pytest
# 删除依赖项
pdm remove requests
# 列出安装的所有包
pdm list
# 列出依赖路径
pdm list pandas --tree
# 根据pyproject.toml安装依赖项
pdm install
以上是从0开始一个新项目的做法。但pdm如何接管老项目?或者如何在 git clone
之后,创建合适的运行环境?
其实,只要项目中存在 requirements.txt
,调用 git init
之后,就可以选择将 requirements.txt
的依赖默认添加到 pyproject.toml
中
如果是 git clone
来的项目,再执行 pdm install
即可
激活默认环境
以上,pdm默认创建名为 in-project
的虚拟环境,这也是当前项目的默认环境。可 pdm venv list
列出
(base) william@winLab:~/proj/tplot$ pdm venv list
Virtualenvs created with this project:
* in-project: /home/william/proj/tplot/.venv
如果你使用VS code,在terminal中cd到项目目录,使用 code .
打开项目,即可自动激活 in-project
虚拟环境
否则,进入python也检测不到虚拟环境中的包。需要使用shell命令激活虚拟环境
(base) william@winLab:~/proj/xplot$ eval $(pdm venv activate in-project)
(xplot-3.10) (base) william@winLab:~/proj/xplot$
快捷命令
在 pyproject.toml
中,可在 [tool.pdm.scripts]
部分自定义快捷命令
[tool.pdm.scripts]
start = "flask run -p 54321"
然后,直接执行以下命令,即可启动flask
pdm run start
如果需要指定运行目录、环境变量,可分别指定`start.cmd, start.working_dir, start.env
所有快捷命令共享的全局环境变量,可指定
[tool.pdm.scripts]
_.env_file = ".env"
切换python版本
可以通过pdm安装多个python版本,会保存在 /home/username/.local/share/pdm/python
目录。这些python版本对所有项目都可见
pdm python install 3.8
# 列出通过pdm安装的python
pdm python list
然后,基于3.8版本创建另一个虚拟环境,会保存在 /home/username/.local/share/pdm/venvs
目录。该虚拟环境仅对当前项目可见
pdm venv create --name test3.8 3.8
此时,如果激活虚拟环境 test3.8
,pdm记录的项目信息,仍然是默认的 in-project
环境
(xplot-3.10) (base) william@winLab:~/proj/xplot$ eval $(pdm venv activate test3.8)
(xplot-3.8) (base) william@winLab:~/proj/xplot$ pdm info
PDM version:
2.15.4
Python Interpreter:
/home/william/proj/xplot/.venv/bin/python (3.10)
Project Root:
/home/william/proj/xplot
如果需要将项目默认环境转换为 test3.8
,使用 pdm use
命令,然后重新安装所需依赖。安装依赖时很有可能报错,可能需要 pdm remove
依赖,重新 pdm add
pdm use --venv test3.8
pdm instll
但是,对同一个项目切换python版本是很少见的需求,一般情况不推荐这么做。更常见的需求是开发python包时的多版本环境测试,此时更推荐使用Nox
结语
以上我们梳理了pdm为Python使用带来的便利。当你需要开发自己的Python包时,pdm的好处会得到淋漓尽致的体现——是的,你可以完全抛弃poetry等传统的开发工具了
但即使你无心开发Python包,pdm也会使你的Python项目结构更加合理、依赖更加清晰,使项目在机器间迁移和扩展的成本降低
玩的开心!