使用PDM来管理Python项目

使用PDM来管理Python项目
鱼六秒概述
使用requirements.txt管理依赖的问题
正在开发一个使用第三方软件包(如fastapi)的Python项目。你需要指定这个依赖,以便其他开发人员和自动化系统能够运行你的应用程序。 于是,你决定在一个requirements.txt文件中包含flask的依赖项:
1 | fastapi |
这时候,一切在本地都正常运行,而在对应用程序进行了一番修改之后,你决定将其部署到生产环境。这就是事情变得有点棘手的地方…
上述的requirements.txt文件没有指定使用fastapi的哪个版本。在这种情况下,通过pip install -r requirements.txt将默认安装最新版本。这是可以的,除非最新版本中有接口或行为更改,导致我们的应用程序出现问题。
举个例子,假设fastapi的作者发布了一个新版本的fastapi。然而,它与你在开发过程中使用的版本不兼容。
现在,假设你将应用程序部署到生产环境并运行pip install -r requirements.txt。Pip获取了最新的不向后兼容的fastapi版本,就这样,你的应用程序在生产环境中崩溃了。
因此,为了解决问题,你尝试在requirements.txt中更加具体。你为fastapi依赖项添加了一个版本说明符。
这也被称为锁定依赖项
1 | fastapi==0.99.0 |
将fastapi依赖项固定到特定版本可以确保pip install -r requirements.txt设置了在开发过程中使用的确切fastapi版本。但它真的能做到吗?
因为fastapi本身也有依赖关系(pip会自动安装),但fastapi本身不为其依赖项指定确切版本。例如,它允许任何版本的starlette>=0.24.0。
同样,为了这个例子,假设发布了一个新版本的starlette,但它为你的应用程序引入了一个致命错误。
当你在生产环境中执行pip install -r requirements.txt时,这一次你将得到fastapi==0.99.0,因为你已经锁定了这个依赖关系。然而,不幸的是,你将获得starlette的最新且有缺陷的版本。再次,产品在生产环境中崩溃。
因此,用包管理pdm解决上述问题。
pdm 是什么
pdm 差不多是 pip + venv,的结合体。可以类似 pip 用于管理第三方模块的管理,但是比 pip 的功能强大许多,同时还包含 venv 的虚拟环境管理功能。大致的功能如下:
- 管理第三方模块的安装与卸载
- 管理虚拟环境
- 管理虚拟环境的依赖
- 管理打包与发布 其中最重要的是 虚拟环境的依赖
名词解释:虚拟环境管理、模块管理、模块依赖管理
虚拟环境
虚拟环境是指内建的 venv 或 virtualenv 、 conda 以及其他用来创建与管理 Python 虚拟环境的工具,不同的虚拟环境各自独立,存放的位置、安装的模块也都不一样。
模块管理、模块依赖管理
模块是指虚拟环境中安装的第三方模块及其版本。大多数项目对第三方库的版本都是有特定要求,如果对旧版本的项目使用新版本的依赖,可能会报很奇怪的错误。
当安装第三方模块时,第三方模块可能会安装自己依赖的模块。当安装两个以上模块时,就可能出现第三方模块的依赖出现冲突。这种情况一般是依赖的版本冲突。这种就叫做相关性依赖
PDM教程
安装
pdm 是一个命令行工具,安装之后就可以使用 pdm 指令。
可以将其安装全局环境或者是虚拟环境,我推荐安装在全局环境,这样在后面使用时不需要单独激活虚拟环境。
1 | pip install pdm |
安装之后就会在 python 解释器的安装目录下的 Scripts 目录里面出现 pdm.exe,因为在安装 python 解释器是配置过环境变量,然后就可以直接全局使用了。
新建项目
首先我们需要创建一个项目目录并且用pdm init初始化:
1 | X:\> mkdir pdm-demo |
然后会跳出来一连串的互动对话,用于创建项目的配置文件,这里我就直接全部一路回车,
此时项目的目录接口如下:
1 | pdm-demo |
看一下生成的 pyproject.toml 配置文件:
1 | [project] |
当您运行 pdm init 命令时,pdm 将要求在项目中使用 Python 解释器,这是安装依赖项和运行任务的基本解释器
与 PEP 582 相比,虚拟环境被认为更成熟,并且在 Python 生态系统和 IDE 中有更好的支持。因此,如果未配置 virtualenv 模式,则默认为 virtualenv 模式。
如果项目解释器(存储在 .pdm.toml 中的解释器,可使用 pdm info 查看)被使用,则将使用虚拟环境。
1 | PDM version: |
自动创建虚拟环境
默认情况下,PDM 倾向于像其他包管理器一样使用 virtualenv 布局。当你第一次在新的 pdm 管理的项目上运行 pdm install 时,它的 Python 解释器还没有确定,pdm 将在 X:/pdm-demo/.venv 目录下创建 virtualenv。Venv,并在其中安装依赖项。在 pdm init 的交互会话中,pdm 还会要求为您创建 virtualenv。
可以选择 PDM 用于创建 virtualenv 的后端。目前它支持三个后端:
- virtualenv(默认)
- venv
- conda
可以通过pdm config venv.backend [virtualenv|venv|conda]更改它。
创建自定义virtualenv
你可以用你想要的任何 Python 版本创建多个虚拟环境:
1 | 创建基于3.11解释器的虚拟环境 |
virtualenv 的位置
PDM 将第一次尝试在项目中创建 virtualenv,除非.venv已经存在。其他virtualenv 将转到 venv.location 配置。它们被命名为 <project_name>-<path_hash>-<name_or_python_version> 避免名称冲突。使用 --name 选项创建的 virtualenv 将始终到此位置。可以通过 pdm config venv.in_project false 禁用在项目中创建 virtualenv。
切换指定venv(必须存在)
可以命令 pdm use -f /path/to/venv
1 | pdm use -f x:\venv\pdmtest\.venv |
如果不确定项目下使用venv,可以命令pdm info
1 | λ pdm info |
列出用这个项目创建的所有 virtualenv
1 | pdm venv list |
移除 virtualenv
1 | pdm venv remove in-project |
激活 virtualenv
pdm-venv 不像 pipenv 和 poetry 那样生成子 shell,而是为您创建 shell,并将激活命令打印到控制台。这样就不会离开当前的外壳。然后你可以把输出给 eval 来激活 virtualenv:
1 | eval $(pdm venv activate in-project) |
