一直以来,我们管理 Python 项目的依赖都是通过手动创建虚拟环境,然后在虚拟环境中安装依赖。这种方式简单且有效,但如果读者尝试过 cargo、npm、yarn 等现代化的依赖管理工具,就会发现 Python 的依赖管理方式有些落后。
何出此言?我们来对比一下 cargo 和 conda 的依赖管理方式:
cargo针对每个项目都会创建一个 Cargo.toml
文件,用于记录项目的依赖信息。这样,我们只需要在 Cargo.toml
中添加依赖,然后执行 cargo build
即可安装依赖。这个过程是声明式的,我们随时可以看到项目的依赖信息,而这份信息也严格地与项目真正的依赖保持一致。
而对于 conda,即便有 environment.yml
文件与 requirements.txt
文件,我们也无法保证这份文件中的依赖与项目真正的依赖保持一致。往往我们改变了项目的依赖后,忘记更新这份文件,导致项目无法正常运行。
从以上的对比我们可以看出, conda 式的项目管理实际上是命令式的,这种以交互的方式构建项目环境的方式天生具有可变性,而 cargo 式的项目管理则是声明式的,这种方式实际上代表了不可变性。而后者是构建可复现系统的基础。
由此,我们引出了一个问题,如何让 Python 的依赖管理更像 cargo 呢?今天,我们介绍一个现代的 Python 依赖管理工具:Poetry。
Poetry
Poetry 是一个 Python 项目的依赖管理工具,它的目标是让 Python 项目的依赖管理更加现代化。Poetry 通过一个 pyproject.toml
文件来管理项目的依赖,这个文件类似于 cargo 的 Cargo.toml
文件。
要安装 Poetry,官方推荐使用 pipx
:
1 | pipx install poetry |
如果你正在使用 Arch Linux
,你可以直接通过 pacman
安装 Poetry:
1 | sudo pacman -S python-poetry |
如果你想同时使用多个版本的 Poetry,你可以通过 asdf
来管理 Poetry 的版本:
1 | asdf plugin add poetry |
安装完成后,我们可以通过 poetry --version
来查看 Poetry 的版本:
1 | poetry --version |
然后,我们使用 Poetry 来创建一个新的 Python 项目:
1 | poetry new poetry-demo |
这个命令会在当前目录下创建一个名为 poetry-demo
的 Python 项目。我们可以进入这个项目,然后查看整个项目结构:
1 | . |
pyproject.toml
我们先来熟悉一下 pyproject.toml
文件,以下是一个新建项目的 pyproject.toml
文件的内容:
1 | [tool.poetry] |
基本配置没有什么好说的,这里只强调一些重要的配置项,更多的配置项可以参考 官方文档。
tool.poetry.package-mode
:指定项目的性质,true
代表项目是一个库,false
代表项目是一个应用程序。tool.poetry.dependencies
:项目的依赖,这里我们可以指定项目的依赖,例如requests = "^2.31.0"
。build-system
:构建系统的配置,可以指定构建系统。
还有一些进阶配置,比如依赖分组、依赖源管理、extra 等,但这些不适合在这篇文章中展开讨论。
添加依赖
我们可以通过 poetry add
命令来添加依赖,例如我们添加一个 requests
依赖:
1 | poetry add requests |
也可以直接在 pyproject.toml
文件中手动添加依赖:
1 | [tool.poetry.dependencies] |
二者的区别是,poetry add
会自动同步虚拟环境中的依赖,而手动添加依赖则需要执行 poetry install
来同步虚拟环境中的依赖。
当添加好依赖后,我们可以执行 poetry run python
来进入虚拟环境,然后引入依赖来测试:
1 | poetry run python |
1 | import requests |
构建项目
只有库项目才能使用 poetry build
命令来构建项目,这个命令会在项目根目录下生成一个 dist
目录,里面包含了项目的构建产物。
1 | poetry build |
发布项目
如果我们想发布项目到 PyPI,我们可以使用 poetry publish
命令:
1 | poetry publish |
这个命令会将项目发布到 PyPI,当然,你需要先在 PyPI 上注册一个账号,鉴于现在的 PyPI 状态,这个步骤暂时无法完成。
作为应用程序
如果我们的项目是一个应用程序,我们可以使用 poetry run
命令来运行项目:
1 | poetry run python -m poetry_demo |
这需要我们在包中拥有一个 __main__.py
文件,这个文件会在我们执行 poetry run python -m poetry_demo
时被执行。
或者,你可以手动执行项目的入口文件:
1 | poetry run python path/to/entry.py |
该入口文件可以是任意 Python 文件。
环境兼容
Poetry 可以使用 requirements.txt
文件来兼容 pip,这样我们可以在 Poetry 与 pip 之间无缝切换。
1 | poetry export -f requirements.txt > requirements.txt |
这个命令会将项目的依赖导出到 requirements.txt
文件中,然后我们可以使用 pip
来安装这些依赖:
1 | pip install -r requirements.txt |
总结
Poetry 实际上更像是一个现代化的 Python 库管理工具,但个人认为,使用 Poetry 的意义在于让我们的项目更加现代化,更加可维护。Poetry 的出现,让我们的 Python 项目管理更加像 cargo,这是一个好的方向。
Poetry 还有诸多进阶功能,将在后续的文章中展开讨论。