npm、pip、pipenv 和 Poetry 包管理器之间的特性比较

Feature comparison between npm, pip, pipenv and Poetry package managers

pippipenvPoetry 包管理器相比,npm 的主要功能如何?我如何使用 pipenv 或 Poetry 的那些功能?

这主要可以帮助某人从 JavaScript 开发人员过渡到 Python 开发人员。

我从未使用过 RubyGems,但将它的主要功能与主要的 Python 包管理器进行比较可能也很有用。帮助来自 Ruby 背景的任何人。

概述

Feature \ Package Manager npm pip pipenv poetry
Access to main repo (i.e. Pypi/npm)
Record top level dependencies Pipfile pyproject.toml
Record development dependencies Pipfile pyproject.toml
Lock versions of all dependencies Pipfile.lock poetry.lock
Switch between interpreter versions nvm
Direct publishing ✓*
Run scripts Pipfile
Editable local packages
Integration with Intellij partial
  • 如果使用第 3 方开发依赖项和将它们绑定在一起的脚本,则可以使用 pipenv 直接发布,请参见下文。

免责声明:我只有 Unix-like systems (OS X 这些包管理器的经验),pipenv 将自己推销为对待 Windows 是第一个 class 公民,我我不确定在没有 pyenv 的情况下如何工作,据我所知,Windows 上不可用。

基本用法

pipenv:

要充分利用 pipenv,应安装 pyenvpipenv 将能够检测和使用随 pyenv 安装的任何版本的 Python,即使它没有被激活。例如,如果 Pipfile 已将 Python 3.4 列为要求:要成功 运行 pipenv installpyenv install 3.4.0 应该首先 运行。

创建新的 Pipfilevenv(使用 Python 3.7.x):

>>> pipenv --python 3.7

或者从现有的 Pipfile.lock 安装依赖项,使用下面的命令。此命令也可用于创建 Pipfile 和 venv(默认为最新可用的 Python 版本)。

>>> pipenv install

在创建的 venv 中执行 运行 命令:

>>> pipenv run <script or command>

例如

>>> pipenv run python main.py

诗歌

Poetry 仍然使用 pyenv,但方式不同:您希望使用的 Python 版本必须在调用 poetry install 或 [=46 之前激活=].

可以使用以下方法创建 pyproject.toml

>>> poetry init

或者可以使用以下方法创建完整的目录结构:

>>> poetry new <dir>

在我们安装之前,我们必须激活一个与 pyproject.toml 文件中指定的相匹配的 Python 版本。

>>> pyenv global <python version specified in pyproject.toml>

现在我们可以使用下面的命令创建 venv,如果存在 poetry.lock 文件,它将安装其中列出的所有依赖项。

>>> poetry install

在创建的 venv 中执行 运行 命令:

>>> poetry run <command>

如果我们使用 pyenv 更改全局 Python 版本,我们将无法再在创建的 venv 中执行 运行 命令。如果我们使用本地创建的 venv,则有一个例外,请参见下文。

运行 您的代码使用不同的 Python 版本

有时最好检查一下您的代码是否适用于 Python 3.7 和 Python 3.4。这不是我们可以想当然的事情。

pipenv

只有在使用不同的 Python 版本重新创建时删除 venv 才有可能:

>>> rm -rf <path to venv>
>>> pipenv --python <different python version>

可能会显示一条警告,指出 venv 的 Python 版本与 Pipfile 中指定的版本不匹配,但据我所知,这只是一条警告。

Multiple parallel environments #1071

诗歌

Poetry 更适合这种用例:可以并排创建多个 venvs。要使用 pyenv 创建和使用新的 venv 开关 Python 版本,然后创建一个新的 venv。

>>> pyenv global <different Python version>
>>> poetry install

如果 Python 版本与 pyproject.toml 中指定的版本不匹配,则会抛出错误,但是可以使用 semantic versioning 指定一系列 Python 版本版本控制。

本地 venv

我更喜欢将我的 venv 安装在我的项目本地的 .venv 文件夹中,这类似于 npm 的工作方式并且允许我删除该文件夹并在发生任何异常情况时重新安装或如果(在 pipenv 的情况下)我想轻松更改我正在使用的 Python 版本。

pipenv

要启用此功能:设置以下环境变量。

>>> export PIPENV_VENV_IN_PROJECT="enabled"

诗歌

可以使用以下命令启用此功能:

>>> poetry config settings.virtualenvs.in-project true

但请注意,这会改变 poetry 的行为,将无法再使用 Python 不同版本之间的快速切换:即使 Python 版本是使用 pyenv 切换所有命令 运行 使用 poetry run 将使用驻留在本地目录中的 venv(及其关联的 Python 版本)。

Option to create virtual environments in the project root (.venv) #108

安装包

pipenv

软件包很容易安装并自动添加到 PipfilePipfile.lock 文件中,使用:

>>> pipenv install [--dev] <package name>

--dev 标志表示开发依赖项。使用pipenv install.

时默认不会安装开发依赖

也可以安装本地包,让您可以处理它们并立即看到您的更改:

>>> pipenv install -e <path to local package>

诗歌

软件包很容易安装并自动添加到 pyproject.tomlpoetry.lock 文件中,使用:

>>> poetry add [--dev] <package name>

--dev 标志表示开发依赖项。使用时默认不会安装开发依赖poetry install,发布时不会添加到包中。

也可以安装本地包,让您可以处理它们并立即看到您的更改:

>>> poetry add --path <path to local package> <name of package>

我不确定为什么需要包的名称,因为它应该已经由本地包定义了。此外,作者似乎不相信 link 一般情况下使用本地包 (pip install -e . equivalent? #34),因此随着时间的推移,此功能可能会被遗忘。

运行 脚本

明确地说,我指的是 npm 调用的脚本,它与 setup.py 文件中指定的脚本不同。

在开发时,有时为难以记忆的命令设置快捷方式很有用,例如 运行 将目录中的每个测试文件设置为:

>>> python -m unittest discover -s <test_folder> -p '*_test.py'

拥有这些命令的快捷方式会方便得多。

pipenv

支持此功能:将以下内容放入Pipfile

[scripts]
    test = "pipenv run python -m unittest discover -s tests -p '*_test.py'"

诗歌

不支持,以后不太可能添加。参见 sdispater's comment to Add tasks #591

发布到 PyPI

最好能够在不制作额外的 setup.py 文件的情况下发布到 PyPI,如果发布包所需的所有信息都包含在包管理文件中,这将是可能的。

pipenv

据我所知,这就是 pipenv 声名狼藉的原因。 setup.py 文件仍然需要发布到 PyPi,不,它们不会自动填充来自 Pipfile.

的依赖项

推荐的方法是在发布时手动复制依赖项,或者获取Pipfile来安装setup.py文件中列出的依赖项,但是setup.py不会自动更新当 运行宁 pipenv install <package name>.

如果您真的希望 Pipfile 依赖于您的 setup.py 文件,可以这样做:

>>> pipenv install '-e .'

Deployment to pypi? #2805, Pipenv: A Guide to the New Python Packaging Tool, and How can I integrate with setup.py? #209.

呸!


所以理想情况下,我们希望从 Pipfile:

派生一个 setup.py 文件

我发现了两个声称可以执行此操作的现有软件包:

  1. pipenv-tools - 但是两年没更新了,src目录下没有代码,我无法正常工作。

  2. Pipenv-Setup - 但它同步 Pipfile.lock 而不是 Pipfile,这是一个反模式。锁定文件用于创建可重现的环境,它过于严格(例如,不允许更新依赖项)用于 setup.py。出于这个原因,我什至没有尝试使用它。


我的解决方案:

我很快写了一个包生成一个install_requires.py文件,可以在setup.py文件中导入:pipenv2setup(是未经 Windows).

测试

有关在发布 pipenv 项目时如何使用包的示例,请参阅此 GitHub 存储库:

An example of using pipenv and pipenv2setup to deploy to Pypi

诗歌

使用 Poetry 发布包非常简单。您根本不需要 setup.py 文件。只需 运行:

>>> poetry publish [--build] [--username <username>] [--password <password>]

可以使用 pip 安装已发布的包,而不仅仅是通过其他 Poetry 实例。

有关如何从使用 setup.py 迁移到纯 pyproject.toml 文件的信息,请参阅此处:Create and Publish a Python Package with Poetry

IntelliJ or PyCharm 整合

pipenv

PyCharm 可以通过 Piplock 文件检测到 venv。但是,使用 PyCharm 界面添加新包不会修改 Piplock 文件。

诗歌

在撰写本文时,PyCharm 似乎没有意识到任何 Poetry 虚拟环境或似乎以任何方式解析 pyproject.toml 文件。

关于诗歌的其他要点

语义版本控制

在 Poetry 中,您必须使用 semantic versioning 指定 Python 和包的版本(必须使用 ~^,而不是 >=<).

Semver: Tilde and Caret

漏洞

Poetry 运行s 使用 Python,但它不适用于旧版本的 Python。所以要为旧版本的 Python 开发:一些命令必须是 运行 并且 pyenv 设置为 >3.6,但是 pyenv 需要切换回用于创建 venv 的旧版本。似乎 venvs 必须大于 3.5。 subprocess.run AttributeError occurred in Python 3.4 #1223

我也不确定 Windows 与 Poetry 的兼容性。

结论

对我来说,poetrypipenv 之间的主要区别在于他们对 pyenv 的使用以及他们直接发布到 PyPI 的能力(或缺乏能力)。诗歌中也缺少剧本,我个人觉得很沮丧。

我发现在使用 Poetry 时,使用 pyenv 在 Python 环境之间切换很多。虽然目前这可以通过使用本地安装的 venv 来缓解。我知道这限制了我在不同 Python 环境中快速测试我的代码的能力,但还有其他工具,例如 tox 可以做到这一点。

使用 Poetry 发布到 PyPI 是如此简单,我在一行中解释了它(上文)。使用 pipenv 发布到 PyPI 是一个雷区,为了解释它,我必须 link 到整个 Git 存储库(上图)。