相比 Pipenv,Poetry 是一个更好的选择

前情提要

Pipenv 描绘了一个好梦,让咱们觉得 Python 也有了其余语言那样完善的包管理器,不过这一切却在后来者 Poetry 这里获得了更好的实现。python

这几年 Pipenv 收获了不少用户,可是也暴露了不少问题。虽然 Lock 太慢、Windows 支持很差和 bug 太多的问题都已经改进了不少,但对我来讲,仍然不能接受随时更新锁定依赖的设定,在上一篇文章《不要用 Pipenv》里也吐槽了不少相关的问题。git

在这篇文章里,我会介绍一个看起来和事实上都更靠谱的 Python 虚拟环境和依赖管理工具 Poetry,做者是 Sébastien Eustace。这是一个新的坑吗?我想并非,尽管这是一个更年轻的工具,1.0 尚未发布,也存在各类各样的 bug,但至少基本使用流程没有问题,用法设计也符合直觉。github

Poetry 是什么

Poetry 和 Pipenv 相似,是一个 Python 虚拟环境和依赖管理工具,另外它还提供了包管理功能,好比打包和发布。你能够把它看作是 Pipenv 和 Flit 这些工具的超集。它可让你用 Poetry 来同时管理 Python 库和 Python 程序。shell

安装 Poetry

官方推荐的安装命令是使用自带的 get-poetry.py 脚本,使用 curl:flask

$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python复制代码

或者直接下载这个安装脚本 get-poetry.py,而后在本地执行。bash

由于这个命令在安装时会从 GitHub 下载一个 7M 的压缩包,若是不用代理某些地区可能会很慢。实际测试使用代理安装耗时约 30 秒,不用代理等了 5 分钟,而后链接被重置。app

若是没有用代理,能够用 pip 安装(不过 Poetry 官方文档不建议这么作,由于有可能会形成依赖冲突,能够考虑用 pipxpipsi):curl

$ pip install --user poetry复制代码

安装后可使用下面的命令确认安装成功:工具

$ poetry --version
Poetry 0.12.17复制代码

若是报错,能够试试从新建立一个命令行会话。学习

附注 在 Mac 上安装报错 ~/.bash_profile 权限错误,临时没管,也能正常运行。后续能够考虑手动把 ~/.poetry/bin 加进去。

Poetry 的基本用法

Poetry 的用法很简单,大部分命令和 Pipenv 接近。咱们须要先了解一些基本概念和 Tips:

  • 使用 PEP 518 引入的新标准 pyproject.toml 文件管理依赖列表和项目的各类 meta 信息,用来替代 Pipfile、requirements.txt、setup.py、setup.cfg、MANIFEST.in 等等各类配置文件。
  • 依赖分为两种,普通依赖(生产环境)和开发依赖。
  • 安装某个包,会在 pyproject.toml 文件中默认使用 upper bound(中文翻译?)版本限定,好比 Flask^1.1。这被叫作 Caret requirements(中文翻译?),好比某个依赖的版本限定是 ^2.9.0,当你执行 poetry update 的时候,它或许会更新到 2.14.0,但不会更新到 3.0.0;假如固定的版本是 ^0.1.11,它可能会更新到 0.1.19,但不会更新到 0.2.0。总之,在更新依赖的时候不会修改最左边非零的数字号版本(对于 SemVer 版本号而言),这样的默认设定能够确保你在更新依赖的时候不会更新到具备不兼容变更的版本。另外也支持更多依赖版本限定符号
  • 不会像 Pipenv 那样随时更新你的锁定依赖版本,锁定依赖存储在 poetry.lock 文件里(这个文件会自动生成)。因此,记得把你的 poetry.lock 文件归入版本控制。
  • 执行 poetry 或 poetry list 命令查看全部可用的命令。

若是你想了解更多进阶的内容,好比设置命令行补全、打包和发布等等,请阅读 Poetry 文档

准备工做

若是你是在一个已有的项目里使用 Poetry,你只须要执行 poetry init 命令来建立一个 pyproject.toml 文件:

$ poetry init复制代码

根据它的提示输入你的项目信息,不肯定的内容就按下 Enter 使用默认值,后续也能够手动更新。指定依赖的环节能够跳过,手动安装会更高效一点。

若是你想建立一个新的 Python 项目,使用 poetry new <文件夹名称> 命令能够建立一个项目模板:

$ poetry new foo复制代码

这会建立一个这样的项目结构:

foo
├── pyproject.toml
├── README.rst
├── foo
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_foo.py复制代码

若是你想使用 src 文件夹,能够添加 --src 选项,这会把程序包嵌套在 src 文件夹里。

建立虚拟环境

使用 poetry install 命令建立虚拟环境(确保当前目录有 pyproject.toml 文件):

$ poetry install复制代码

这个命令会读取 pyproject.toml 中的全部依赖(包括开发依赖)并安装,若是不想安装开发依赖,能够附加 --no-dev 选项。若是项目根目录有 poetry.lock 文件,会安装这个文件中列出的锁定版本的依赖。若是执行 add/remove 命令的时候没有检测到虚拟环境,也会为当前目录自动建立虚拟环境。

激活虚拟环境

执行 poetry 开头的命令并不须要激活虚拟环境,由于它会自动检测到当前虚拟环境。若是你想快速在当前目录对应的虚拟环境中执行命令,可使用 poetry run <你的命令> 命令,好比:

$ poetry run python app.py复制代码

若是你想显式的激活虚拟环境,使用 poetry shell 命令:

$ poetry shell复制代码

安装包

使用 poetry add 命令来安装一个包:

$ poetry add flask复制代码

添加 --dev 参数能够指定为开发依赖:

$ poetry add pytest --dev复制代码

追踪 & 更新包

使用 poetry show 命令能够查看全部安装的依赖(能够传递包名称做为参数查看具体某个包的信息):

$ poetry show复制代码

添加 --tree 选项能够查看依赖关系:

$ poetry show --tree复制代码

添加 --outdated 能够查看能够更新的依赖:

$ poetry show --outdated复制代码

执行 poetry update 命令能够更新全部锁定版本的依赖:

$ poetry update复制代码

若是你想更新某个指定的依赖,传递包名做为参数:

$ poetry update foo复制代码

卸载包

使用 poetry remove <包名称> 卸载一个包:

$ poetry remove foo复制代码

经常使用配置

Poetry 的配置存储在单独的文件中,比 Pipenv 设置环境变量的方式要方便一点。配置经过 poetry config 命令设置,好比下面的命令能够写入 PyPI 的帐号密码信息:

$ poetry config http-basic.pypi username password复制代码

下面的命令设置在项目内建立虚拟环境文件夹:

$ poetry config settings.virtualenvs.in-project true复制代码

另外一个经常使用的配置是设置 PyPI 镜像源,以使用豆瓣提供的 PyPI 镜像源为例,你须要在 pyproject.toml 文件里加入这部份内容:

[[tool.poetry.source]]
name = "douban"
url = "https://pypi.doubanio.com/simple/"复制代码

不过通过测试 Poetry 会使用 pip.ini 设置的 PyPI 镜像,并且豆瓣的源好像好久没更新了(建立虚拟环境安装的默认依赖里 importlib-metadata==0.20 找不到),这篇文章列出了一些其余国内的 PyPI 源。

总结

总的来讲,我愿意深刻尝试和使用 Poetry。固然,通过使用 Pipenv 的痛苦经历,我对推荐工具这种事情变得更保守了。因此我不推荐 Python 初学者使用,不推荐直接在生产环境使用,不推荐无法正常访问国际互联网的人使用。

列一些我了解到的优缺点:

优势

  • 使用标准的 pyproject.toml 标准,不用写多个配置文件
  • 同时支持管理 Python 程序和 Python 库
  • 更符合直觉的默认设计,好比不会随便更新锁定版本的依赖
  • 干净简洁的命令行输出,没有星星和蛋糕
  • 安装包的时候,使用 upper bound 版本限定,而不是 Pipenv 默认的通配符
  • 卸载包的时候,直接卸载孤立的子依赖,不须要像 Pipenv 那样须要再执行 pipenv clean

缺点

  • 「poetry」这个单词有一点难打……
  • 引入新的 pyproject.toml 标准,旧项目须要一点迁移成本和学习成本
  • 会有一些潜在的 bug
  • 解析依赖的过程偶尔会久一点
  • 对虚拟环境的管理控制有些弱,没有 Pipenv 那样的删除虚拟环境和清空依赖的操做
  • 缺乏一个稳定的维护团队,有大量 issue 和 PR 等待处理,但状况在逐渐好转

固然,你仍是能够选择继续使用 virtualenv 和 pip 这些基础工具,直到有一个完美的解决方案出现。或者,也能够选择试试新东西,而后尝试改进它,让完美的解决方案早一点出现。

(2)


原标题是「相比 Pipenv,Poetry 是一个更好的选择吗?」

相关文章
相关标签/搜索