光阴冢 赛博空间的自留地

使用 Poetry 管理 Python 项目

虽然后来 Python 写得越来越少,但是还是要和一些使用 Python 的项目打交道,并且发现许多同学对于 Python 的虚拟环境,包管理等问题并不是很熟悉,因此写这篇博客梳理一下,希望对其他人有所帮助。

TL;DR

  • 使用 pyenv 切换不同版本的 python
  • 使用 poetry 在不同 python 下管理项目依赖和虚拟环境
  • 绝不使用 sudo pip install 安装 python 包
  • 绝不使用 sudo make install 安装 python

Python 版本选择问题

除了特殊的本身就对于多版本软件有良好支持的发行版(例如 NixOS)以外,系统上安装的 python 最多只有两个大版本,2.x 和 3.x,这些 python 已经被系统包管理器处理好了各自的依赖关系,有时候甚至会用到系统关键组件中去。因此,除非知道自己在做什么,绝对不要使用 sudo pip install 或者 make install 来在全局安装 python 库 或者全新的 python 版本。

我目前所使用的多版本管理方案是 pyenv,能够在不同的 python 版本中自由切换。

如果你只想要 python2 或者 python3,对小版本号没有过多的需求,那么没必要去使用 pyenv,可以在开发时直接使用后文提到的 poetry 来管理项目。

安装个人使用的软件包

通过 pip install --user 能够为当前环境中 pip 所对应的 python 版本 在用户目录下安装软件包。如果对于个人所需要使用的软件包,同时系统包管理器又没有提供的,推荐在(使用 pyenv )选择了合适的 python 版本之后,用这种方式安装。

同时,需要将安装之后的 bin 路径添加到环境变量中,通常是 $HOME/.local/bin。添加后即可直接在命令行中使用了。

Poetry 和虚拟环境

在开发一个项目的时候,很可能需要安装许多软件包,这些软件包有可能还需要指定版本,因此与本地版本冲突,这时我们就需要虚拟环境进行隔离。虚拟环境是一个干净的 python 环境,在这个环境中进行 python 软件包的安装并不会影响其他虚拟环境或者系统环境, python3.3 之后通常使用自带的 venv 来实现。

在开发时,很常见的需求是需要复现环境,安装需要的软件包,通过 requirements.txt (原生 python)或者通过 Pipfile (pipenv)都可以,前者对于软件包的互相依赖没有很好的支持,后者的 lock 时间在项目稍微大一点的时候就令人发怵。

poetry 是一个更现代的 python 软件包管理器。

通过 systemd 运行指定 python 任务

以下是我使用的一个 Unit file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[Unit]
Description=IUyhiuasd
After=network.target

[Service]
Type=simple
RemainAfterExit=true
WorkingDirectory=/usr/share/webapps/IUyhiuasd
ExecStart=/usr/bin/poetry run gunicorn wsgi:app
StandardOutput=journal

[Install]
WantedBy=multi-user.target

poetry 更换软件源

pyproject.toml 里加入

1
2
3
[[tool.poetry.source]]
name = "zju"
url = "https://mirrors.zju.edu.cn/pypi/web/simple"

构建软件包并且指定可执行的脚本

执行 poetry build 即可构建软件包。

指定可执行程序的函数入口:

1
2
[tool.poetry.scripts]
abc = "bca.abc:main"

表示安装了最终构建的 wheel 包以后,有一个可执行文件叫做 abc,运行之后会执行 bca/abc.py 中的 main 函数的内容。