提交 e00a689a 编写于 作者: 写代码的明哥's avatar 写代码的明哥

add 《pdm 入门使用教程》

上级 a370e930
# 划时代的 Python 包管理工具 -- PDM
PDM 是一个新的 Python 的包管理器,也许你还未知晓它的存在,但实际上PDM 已经诞生两年,并在 2021 年发布 1.0 版本,目前最高的版本是 1.12.8。
在刚听到 PDM 时,我下意识认为它是 Python Development Manager,又一个和 Pipenv 和 Poetry 一样换汤不换药的虚拟环境管理工具。
一直到我翻到了作者的博客,才知道 PDM 的全称是 Python Development Master,比我想像的还要牛逼一个档次。
值得一提的是,PDM 的作者是 PyPa 成员、Pipenv 目前主要的维护者之一,最重要的是,是他是中国人,因此这是一款国人开发的工具。
## 1. Why PDM?
早期的包管理器(如 Pipevn,Poetry),都是基于虚拟环境的,虚拟环境主要是为了隔离项目开发环境,但如果涉及到虚拟 环境嵌套虚拟环境,问题就难搞了,经常会出现问题。
PDM 得益于一个 2018 年的 PEP 提案(PEP582,Python local packages directory),完全摒弃了虚拟环境。
[作者的博客](https://frostming.com/2020/02-28/pdm-introduction/)上来看,当初之所以要重复造个轮子,完全是因为 Pipenv 和 Poetry 都不够好用,正好有 PEP582 ,可以开发一个划时代的 Python 包管理工具,它就是 PDM 。
PDM 包含如下特性:
- PEP 582 本地项目库目录,支持安装与运行命令,**完全不需要虚拟环境**
- 一个简单且相对快速的依赖解析器,特别是对于大的二进制包发布。
- 兼容 PEP 517 的构建后端,用于构建发布包(源码格式与 wheel 格式)
- 拥有灵活且强大的插件系统(有插件系统直接就拉开一个档次)
- [PEP 621](https://www.python.org/dev/peps/pep-0621) 元数据格式
-[pnpm](https://pnpm.io/motivation#saving-disk-space-and-boosting-installation-speed) 一样的中心化安装缓存,节省磁盘空间
尽管 PDM 是国人开发,但考虑到国际化,官网文档是全英文的。
我花了整整一天,通读完文档,消化了 70% 的 PDM 用法,现将心得整理分享出来,会对你上手 PDM 有帮助。
关于 PDM,内容挺多的,打算分两篇文章来完整地介绍它:
- 面向新手的入门级教程
- 面向骨灰级选手的教程
本篇是第一篇,先让大家对 pdm 的基本用法有一个框架性的理解,而 pdm 真正竞争力请持续关注后续文章。
## 2. 安装 PDM
PDM 的安装方法有很多种,在官网上就有 6 种,比如 pip、pipx、homebrew 等
在以前的文章中,我推荐过 pipx 工具,在安装那种命令行应用的包时非常好用。
而此时 PDM 就是一个命令行工具,因此我也推荐使用 pipx 安装,方便统一对命令行进行管理
执行 pipx install pdm 即可安装
![](http://image.iswbm.com/image-20220212200413787.png)
PDM 只有 Python 3.7+ 的版本才能使用,使用其他的方法安装,要先保证你的 Python 版本,但使用 pipx 则不需要你去操心。
## 3. 初始化 PDM
执行 pdm init 就会开始初始化,初始化的时候,会让你选择项目的一些信息
- 是否要上传 PyPI
- 依赖的 Python 版本
- License 类型
- 作者信息
- 邮箱信息
我机器上有 Python 2.7 和 Python 3.10 两个版本,在初始化项目时会把机器上的所有 Python 版本都扫描出来了,会让选择项目的 Python 版本。
![](http://image.iswbm.com/image-20220212204609288.png)
完成之后,PDM 会将你的选择以 toml 格式写入 pyproject.toml 配置文件中。
![](http://image.iswbm.com/image-20220212204627731.png)
## 4. PDM 用法
pdm 有非常多的命令,使用 `-h` 可以看到帮助菜单
![](http://image.iswbm.com/image-20220212204708840.png)
### 4.1 安装包
和 Poetry 一样,安装使用的是 add 命令,但 pdm 的 add 比 poetry 好用,主要体现在分组,具体请关注后续文章
![](http://image.iswbm.com/image-20220212205148934.png)
### 4.2 查看包
使用 pdm list 可以以列表形式列出当前环境已安装的包
![](http://image.iswbm.com/image-20220212205220953.png)
再加个 `--graph` 就能以树状形式查看,直接依赖包和间接依赖包关系的层级一目了然
![](http://image.iswbm.com/image-20220212222032290.png)
pdm list 还有两个选项:
- `--freeze`:以 requirements.txt 的格式列出已安装的包
- `--json`:以 json 的格式列出已安装的包,但必须与 `--graph` 同时使用
要查看某个包的某体详情,直接用 pdm show 即可
![](http://image.iswbm.com/image-20220212211203788.png)
### 4.3 删除包
删除包使用的是 remove 命令
![](http://image.iswbm.com/image-20220212215831751.png)
### 4.4 项目配置
不加任何参数,可以打印出该项目的环境配置
![](http://image.iswbm.com/image-20220212211303563.png)
想要修改的话,只要加 key 和 value 做为参数即可,以修改 pypi 镜像代理为例
原来上面是豆瓣源,现在我要改成阿里源,只需要执行如下命令,可比 poetry 方便多啦~
![](http://image.iswbm.com/image-20220212212225849.png)
pdm config 里面有非常多的配置,想要一一搞清楚的可以去官网查阅:https://pdm.fming.dev/configuration/
### 4.5 运行命令
想要在 pdm 的环境中执行命令或者项目,可以使用 run 命令,若是执行项目时,有诸多参数,可以在 pyproject.toml 配置命令别名,具体用法,请往后看
![](http://image.iswbm.com/image-20220212211033303.png)
### 4.6 查看环境
使用 `info` 命令,可以查看当前项目的环境信息
![](http://image.iswbm.com/image-20220212223811269.png)
### 4.7 更新包
更新的话,简单的场景下,使用下面这两条即可
```bash
# 更新所有包
pdm update
# 更新某个包
pdm update <pkg>
```
复杂的场景,pdm 也都为你考虑到了,它提供了很多选项,可以根据需要使用(以下如有解释错误,请帮忙指正)
- `--save-compatible`:项目依赖可兼容的版本
- `--save-wildcard`:保存通配符版本(暂不明白)
- `--save-exact`:保存有指定确切版本的包
- `--save-minimum`:保持最小版本的包
- `--update-reuse`:尽量只更新命令行中指定的包,其依赖包能不更新则不更新
- `--update-eager`:更新某个包顺带更新其依赖包(递归升级)
- `--prerelease`:允许提前释放(暂不明白)
- `--unconstrained`:忽略包版本的约束,可将包升级至最新版本
- `--top`:仅更新有在 pyproject.toml 的包
- `--dry-run`:试运行,而不去修改 lock 文件
- `--no-sync`:只更新 lock 文件,但不更新包
如果你的依赖包有设置分组,还可以指定分组进行更新
```bash
pdm update -G security -G http
```
也可以指定分组更新分组里的某个包
```bash
pdm update -G security cryptography
```
再加个 `-d` 就可以再指定 dev 依赖
``` bash
# 更新所有的 dev 依赖
pdm update -d
# 更新 dev 依赖下某个分组的某个包
pdm update -dG test pytest
```
同样地,也可以指定 `--prod` 或者 `--production` 升级非 dev (即生产)的包。
### 4.8 切换 py
当你在初始化 pdm 项目时,就已经选定了当前的 Python 版本和可用的 Python 版本范围,后面如果想更改,可以使用 use 命令,但版本要受之前设定的版本范围约束。
假设允许范围是 python 3.9+,当前使用的是 python 3.10,可以直接切换过去。
```
pdm use python3.9
```
## 5. 命令别名
在 pyproject.toml 添加 `[tool.pdm.scripts]` 可以设置快捷命令别名,若项目的执行有非常多的参数,这种设定别名的方法将很有用。
![](http://image.iswbm.com/image-20220213001224815.png)
`[tool.pdm.scripts]` 有两种形式
```toml
# 第一种
[tool.pdm.scripts]
start = "python main.py"
# 第一种
[tool.pdm.scripts]
start = {cmd = "python main.py"}
```
但若想在参数中加注释,就必须得使用第二种方法,例如这样
```toml
[tool.pdm.scripts]
start = {cmd = [
"flask",
"run",
# Important comment here about always using port 54321
"-p", "54321"
]}
```
除了 cmd 之外,还有两个参数
一个是 shell 参数,从输出来看你应该和看出和 cmd 的区别,和 `subprocess.Popen()` with `shell=True` 差不多一个意思
![](http://image.iswbm.com/image-20220213003342952.png)
一个是 env_file 参数,可以指定配置环境变量的文件
```toml
[tool.pdm.scripts]
start.cmd = "flask run -p 54321"
start.env_file = ".env"
```
如果想要把这个环境变量的文件不仅限于某个命令,而是 pdm run 全局,可以这样配置
```toml
[tool.pdm.scripts]
_.env_file = ".env"
```
`--list` 或者 `-l`可以查看所有设置的快捷别名
![](http://image.iswbm.com/image-20220213003948180.png)
对于每一个快捷命令,都可以设置 pre 和 post 命令:
- pre 命令:在每次快捷命令执行前会执行
- post 命令:在每次快捷命令执行后会执行
```toml
[tool.pdm.scripts]
pre_compress = "{{ Run BEFORE the `compress` script }}"
compress = "tar czvf compressed.tar.gz data/"
post_compress = "{{ Run AFTER the `compress` script }}"
```
## 6. 自动补全
pdm 的命令虽多,但并不复杂,并不太需要使用自动补全,若你真的需要补全,也可以实现。
对于不同的 shell,自动补全的配置方式都不太一样,这个在官网上有详细的说明。
如果你和我一样使用的 zsh,可以参照我的配置方式。
![](http://image.iswbm.com/image-20220212214047051.png)
截图中间有一步是 vim ~/.zshrc ,是将 pdm 插件配置到 zsh 中
```
plugins=(git z macos extract zsh-syntax-highlighting zsh-autosuggestions pdm)
```
## 7. 方案兼容
### 其他方案迁移到 pdm
pdm 足够好用,也足够开放,如果你当前使用的是其他的包管理器,比如 pipenv ,poetry,或者还在用最原始的 requirements.txt ,你也可以很方便的迁移到 pdm 中来:
- 使用 pdm import -f {file} 无需初始化,直接转换
- 执行 pdm init 或者 pdm install 的时候,会自动识别你当前的依赖情况并转换
### pdm 迁移到其他方案
同样的,你也可以当 pdm 管理的项目,导出为其他方案
pyproject.toml 和 pdm.lock是 pdm 的两个核心文件。
pdm 做为一个后起之秀,也没有忘记向前兼容,它支持:
- 将 pyproject.toml 转成 setup.py
```bash
pdm export -f setuppy -o setup.py
```
- 将 pdm.lock 转成 requirements.txt
```bash
pdm export -o requirements.txt
```
## 8. 总结一下
花了很大的力气,终于把 PDM 的基本用法给介绍完毕,相信一定会有人会提出质疑:这就是你所谓的 **划时代的包管理器**
实际上,上面仅仅是入门操作,而 PDM 的一些核心知识,考虑到篇幅有限,我将这些进阶类的内容安排在后续文章,它将包括但不仅限于:
- PDM 的原理剖析:PEP 582 提案
- 发布包的构建:PEP 517 提案
- Hook 脚本的定义与使用
- 插件管理系统与自定义插件
- 缓存管理系统的介绍
这些内容是 PDM 的核心,只有理解了这些,你才能真正用好 PDM,到那时你会感慨:**为什么 Guido 还不把这样的工具收编成标准的包管理工具?**
\ No newline at end of file
划时代的 Python 包管理工具 – PDM
================================
PDM 是一个新的 Python 的包管理器,也许你还未知晓它的存在,但实际上PDM
已经诞生两年,并在 2021 年发布 1.0 版本,目前最高的版本是 1.12.8。
在刚听到 PDM 时,我下意识认为它是 Python Development Manager,又一个和
Pipenv 和 Poetry 一样换汤不换药的虚拟环境管理工具。
一直到我翻到了作者的博客,才知道 PDM 的全称是 Python Development
Master,比我想像的还要牛逼一个档次。
值得一提的是,PDM 的作者是 PyPa 成员、Pipenv
目前主要的维护者之一,最重要的是,是他是中国人,因此这是一款国人开发的工具。
1. Why PDM?
------------
早期的包管理器(如
Pipevn,Poetry),都是基于虚拟环境的,虚拟环境主要是为了隔离项目开发环境,但如果涉及到虚拟
环境嵌套虚拟环境,问题就难搞了,经常会出现问题。
PDM 得益于一个 2018 年的 PEP 提案(PEP582,Python local packages
directory),完全摒弃了虚拟环境。
从\ `作者的博客 <https://frostming.com/2020/02-28/pdm-introduction/>`__\ 上来看,当初之所以要重复造个轮子,完全是因为
Pipenv 和 Poetry 都不够好用,正好有 PEP582 ,可以开发一个划时代的 Python
包管理工具,它就是 PDM 。
PDM 包含如下特性:
- PEP 582
本地项目库目录,支持安装与运行命令,\ **完全不需要虚拟环境**\ 。
- 一个简单且相对快速的依赖解析器,特别是对于大的二进制包发布。
- 兼容 PEP 517 的构建后端,用于构建发布包(源码格式与 wheel 格式)
- 拥有灵活且强大的插件系统(有插件系统直接就拉开一个档次)
- `PEP 621 <https://www.python.org/dev/peps/pep-0621>`__ 元数据格式
- 像
`pnpm <https://pnpm.io/motivation#saving-disk-space-and-boosting-installation-speed>`__
一样的中心化安装缓存,节省磁盘空间
尽管 PDM 是国人开发,但考虑到国际化,官网文档是全英文的。
我花了整整一天,通读完文档,消化了 70% 的 PDM
用法,现将心得整理分享出来,会对你上手 PDM 有帮助。
关于 PDM,内容挺多的,打算分两篇文章来完整地介绍它:
- 面向新手的入门级教程
- 面向骨灰级选手的教程
本篇是第一篇,先让大家对 pdm 的基本用法有一个框架性的理解,而 pdm
真正竞争力请持续关注后续文章。
2. 安装 PDM
-----------
PDM 的安装方法有很多种,在官网上就有 6 种,比如 pip、pipx、homebrew 等
在以前的文章中,我推荐过 pipx 工具,在安装那种命令行应用的包时非常好用。
而此时 PDM 就是一个命令行工具,因此我也推荐使用 pipx
安装,方便统一对命令行进行管理
执行 pipx install pdm 即可安装
.. image:: http://image.iswbm.com/image-20220212200413787.png
PDM 只有 Python 3.7+ 的版本才能使用,使用其他的方法安装,要先保证你的
Python 版本,但使用 pipx 则不需要你去操心。
3. 初始化 PDM
-------------
执行 pdm init 就会开始初始化,初始化的时候,会让你选择项目的一些信息
- 是否要上传 PyPI
- 依赖的 Python 版本
- License 类型
- 作者信息
- 邮箱信息
我机器上有 Python 2.7 和 Python 3.10
两个版本,在初始化项目时会把机器上的所有 Python
版本都扫描出来了,会让选择项目的 Python 版本。
.. image:: http://image.iswbm.com/image-20220212204609288.png
完成之后,PDM 会将你的选择以 toml 格式写入 pyproject.toml 配置文件中。
.. image:: http://image.iswbm.com/image-20220212204627731.png
4. PDM 用法
-----------
pdm 有非常多的命令,使用 ``-h`` 可以看到帮助菜单
.. image:: http://image.iswbm.com/image-20220212204708840.png
4.1 安装包
~~~~~~~~~~
和 Poetry 一样,安装使用的是 add 命令,但 pdm 的 add 比 poetry
好用,主要体现在分组,具体请关注后续文章
.. image:: http://image.iswbm.com/image-20220212205148934.png
4.2 查看包
~~~~~~~~~~
使用 pdm list 可以以列表形式列出当前环境已安装的包
.. image:: http://image.iswbm.com/image-20220212205220953.png
再加个 ``--graph``
就能以树状形式查看,直接依赖包和间接依赖包关系的层级一目了然
.. image:: http://image.iswbm.com/image-20220212222032290.png
pdm list 还有两个选项:
- ``--freeze``\ :以 requirements.txt 的格式列出已安装的包
- ``--json``\ :以 json 的格式列出已安装的包,但必须与 ``--graph``
同时使用
要查看某个包的某体详情,直接用 pdm show 即可
.. image:: http://image.iswbm.com/image-20220212211203788.png
4.3 删除包
~~~~~~~~~~
删除包使用的是 remove 命令
.. image:: http://image.iswbm.com/image-20220212215831751.png
4.4 项目配置
~~~~~~~~~~~~
不加任何参数,可以打印出该项目的环境配置
.. image:: http://image.iswbm.com/image-20220212211303563.png
想要修改的话,只要加 key 和 value 做为参数即可,以修改 pypi 镜像代理为例
原来上面是豆瓣源,现在我要改成阿里源,只需要执行如下命令,可比 poetry
方便多啦~
.. image:: http://image.iswbm.com/image-20220212212225849.png
pdm config
里面有非常多的配置,想要一一搞清楚的可以去官网查阅:https://pdm.fming.dev/configuration/
4.5 运行命令
~~~~~~~~~~~~
想要在 pdm 的环境中执行命令或者项目,可以使用 run
命令,若是执行项目时,有诸多参数,可以在 pyproject.toml
配置命令别名,具体用法,请往后看
.. image:: http://image.iswbm.com/image-20220212211033303.png
4.6 查看环境
~~~~~~~~~~~~
使用 ``info`` 命令,可以查看当前项目的环境信息
.. image:: http://image.iswbm.com/image-20220212223811269.png
4.7 更新包
~~~~~~~~~~
更新的话,简单的场景下,使用下面这两条即可
.. code:: bash
# 更新所有包
pdm update
# 更新某个包
pdm update <pkg>
复杂的场景,pdm
也都为你考虑到了,它提供了很多选项,可以根据需要使用(以下如有解释错误,请帮忙指正)
- ``--save-compatible``\ :项目依赖可兼容的版本
- ``--save-wildcard``\ :保存通配符版本(暂不明白)
- ``--save-exact``\ :保存有指定确切版本的包
- ``--save-minimum``\ :保持最小版本的包
- ``--update-reuse``\ :尽量只更新命令行中指定的包,其依赖包能不更新则不更新
- ``--update-eager``\ :更新某个包顺带更新其依赖包(递归升级)
- ``--prerelease``\ :允许提前释放(暂不明白)
- ``--unconstrained``\ :忽略包版本的约束,可将包升级至最新版本
- ``--top``\ :仅更新有在 pyproject.toml 的包
- ``--dry-run``\ :试运行,而不去修改 lock 文件
- ``--no-sync``\ :只更新 lock 文件,但不更新包
如果你的依赖包有设置分组,还可以指定分组进行更新
.. code:: bash
pdm update -G security -G http
也可以指定分组更新分组里的某个包
.. code:: bash
pdm update -G security cryptography
再加个 ``-d`` 就可以再指定 dev 依赖
.. code:: bash
# 更新所有的 dev 依赖
pdm update -d
# 更新 dev 依赖下某个分组的某个包
pdm update -dG test pytest
同样地,也可以指定 ``--prod`` 或者 ``--production`` 升级非 dev
(即生产)的包。
4.8 切换 py
~~~~~~~~~~~
当你在初始化 pdm 项目时,就已经选定了当前的 Python 版本和可用的 Python
版本范围,后面如果想更改,可以使用 use
命令,但版本要受之前设定的版本范围约束。
假设允许范围是 python 3.9+,当前使用的是 python 3.10,可以直接切换过去。
::
pdm use python3.9
5. 命令别名
-----------
在 pyproject.toml 添加 ``[tool.pdm.scripts]``
可以设置快捷命令别名,若项目的执行有非常多的参数,这种设定别名的方法将很有用。
.. image:: http://image.iswbm.com/image-20220213001224815.png
``[tool.pdm.scripts]`` 有两种形式
.. code:: toml
# 第一种
[tool.pdm.scripts]
start = "python main.py"
# 第一种
[tool.pdm.scripts]
start = {cmd = "python main.py"}
但若想在参数中加注释,就必须得使用第二种方法,例如这样
.. code:: toml
[tool.pdm.scripts]
start = {cmd = [
"flask",
"run",
# Important comment here about always using port 54321
"-p", "54321"
]}
除了 cmd 之外,还有两个参数
一个是 shell 参数,从输出来看你应该和看出和 cmd 的区别,和
``subprocess.Popen()`` with ``shell=True`` 差不多一个意思
.. image:: http://image.iswbm.com/image-20220213003342952.png
一个是 env_file 参数,可以指定配置环境变量的文件
.. code:: toml
[tool.pdm.scripts]
start.cmd = "flask run -p 54321"
start.env_file = ".env"
如果想要把这个环境变量的文件不仅限于某个命令,而是 pdm run
全局,可以这样配置
.. code:: toml
[tool.pdm.scripts]
_.env_file = ".env"
加 ``--list`` 或者 ``-l``\ 可以查看所有设置的快捷别名
.. image:: http://image.iswbm.com/image-20220213003948180.png
对于每一个快捷命令,都可以设置 pre 和 post 命令:
- pre 命令:在每次快捷命令执行前会执行
- post 命令:在每次快捷命令执行后会执行
.. code:: toml
[tool.pdm.scripts]
pre_compress = "{{ Run BEFORE the `compress` script }}"
compress = "tar czvf compressed.tar.gz data/"
post_compress = "{{ Run AFTER the `compress` script }}"
6. 自动补全
-----------
pdm
的命令虽多,但并不复杂,并不太需要使用自动补全,若你真的需要补全,也可以实现。
对于不同的
shell,自动补全的配置方式都不太一样,这个在官网上有详细的说明。
如果你和我一样使用的 zsh,可以参照我的配置方式。
.. image:: http://image.iswbm.com/image-20220212214047051.png
截图中间有一步是 vim ~/.zshrc ,是将 pdm 插件配置到 zsh 中
::
plugins=(git z macos extract zsh-syntax-highlighting zsh-autosuggestions pdm)
7. 方案兼容
-----------
其他方案迁移到 pdm
~~~~~~~~~~~~~~~~~~
pdm 足够好用,也足够开放,如果你当前使用的是其他的包管理器,比如 pipenv
,poetry,或者还在用最原始的 requirements.txt ,你也可以很方便的迁移到
pdm 中来:
- 使用 pdm import -f {file} 无需初始化,直接转换
- 执行 pdm init 或者 pdm install
的时候,会自动识别你当前的依赖情况并转换
pdm 迁移到其他方案
~~~~~~~~~~~~~~~~~~
同样的,你也可以当 pdm 管理的项目,导出为其他方案
pyproject.toml 和 pdm.lock是 pdm 的两个核心文件。
pdm 做为一个后起之秀,也没有忘记向前兼容,它支持:
- 将 pyproject.toml 转成 setup.py
.. code:: bash
pdm export -f setuppy -o setup.py
- 将 pdm.lock 转成 requirements.txt
.. code:: bash
pdm export -o requirements.txt
8. 总结一下
-----------
花了很大的力气,终于把 PDM
的基本用法给介绍完毕,相信一定会有人会提出质疑:这就是你所谓的
**划时代的包管理器** ?
实际上,上面仅仅是入门操作,而 PDM
的一些核心知识,考虑到篇幅有限,我将这些进阶类的内容安排在后续文章,它将包括但不仅限于:
- PDM 的原理剖析:PEP 582 提案
- 发布包的构建:PEP 517 提案
- Hook 脚本的定义与使用
- 插件管理系统与自定义插件
- 缓存管理系统的介绍
这些内容是 PDM 的核心,只有理解了这些,你才能真正用好
PDM,到那时你会感慨:\ **为什么 Guido
还不把这样的工具收编成标准的包管理工具?**
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册