npm、pip、pipenv 和诗歌包管理器的功能比较 [英] Feature comparison between npm, pip, pipenv and poetry package managers
问题描述
npm
的主要特性与 pip
、pipenv
和 poetry
包管理器相比如何?以及如何使用 pipenv
或 poetry
的这些功能?
这主要可以帮助某人从 JavaScript 开发人员过渡到 Python 开发人员.
我从未使用过使用过的 rubygems,但将其主要功能与主要的 python 包管理器进行比较也可能很有用.帮助任何有红宝石背景的人.
概述
功能\包管理器 | npm | 点 | pipenv | 诗歌 |
---|---|---|---|---|
访问主仓库(即 Pypi/npm) | ✓ | ✓ | ✓ | ✓ |
记录顶级依赖 | ✓ | ✗ | pipfile | pyproject.toml |
记录开发依赖 | ✓ | ✗ | pipfile | pyproject.toml |
锁定所有依赖的版本 | ✓ | ✓ | pipfile.lock | poetry.lock |
在解释器版本之间切换 | nvm | ✗ | ✗ | ✓ |
直接发布 | ✓ | ✗ | ✓* | ✓ |
运行脚本 | ✓ | ✗ | pipfile | ✗ |
可编辑的本地包 | ✓ | ✓ | ✓ | ✓ |
与 Intellij 的集成 | ✓ | ✓ | 部分 | ✗ |
- 如果使用 3rd 方开发依赖项和将它们绑定在一起的脚本,则可以使用
pipenv
直接发布,见下文.
免责声明:我只在NIX 系统(特别是 OSX)上使用过这些包管理器",pipenv
将自己推销为将 Windows 视为一等公民,我不确定这是如何工作的没有 pyenv
,据我所知,它在 Windows 上不可用.
基本用法
pipenv:
为了充分利用 pipenv
,应该安装 pyenv
.pipenv
将能够检测和使用安装了 pyenv
的任何版本的 python,即使它没有被激活.例如,如果 Pipfile
已将 python 3.4 列为要求:要成功运行 pipenv install
,应首先运行 pyenv install 3.4.0
.
要创建一个新的 Pipfile
和 venv(使用 python 3.7.x):
或者从现有的 Pipfile.lock
安装依赖项,使用下面的命令.此命令还可用于创建 Pipfile
和 venv(默认为最新的可用 Python 版本).
在创建的 venv 中运行命令:
<预><代码>>>>pipenv 运行<脚本或命令>例如
<预><代码>>>>pipenv 运行 python main.py诗歌
Poetry 仍然使用 pyenv
,但方式不同:在调用 poetry install
或 poetry run之前,必须激活您希望使用的 python 版本.代码>.
可以使用以下方法创建 pyproject.toml
:
或者可以使用以下方法创建完整的目录结构:
<预><代码>>>>诗新 <dir>在安装之前,我们必须激活与 pyproject.toml
文件中指定的内容相匹配的 Python 版本.
现在我们可以使用下面的命令创建 venv,如果存在 poetry.lock
文件,它将安装其中列出的所有依赖项.
在创建的 venv 中运行命令:
<预><代码>>>>诗歌运行<命令>如果我们使用 pyenv
更改全局 python 版本,我们将不再能够在创建的 venv 中运行命令.如果我们使用本地创建的 venv,则有一个例外,见下文.
使用不同的 python 版本运行你的代码
有时最好检查一下您的代码是否适用于 python 3.7 和 python 3.4.这不是我们可以认为理所当然的.
pipenv
只能通过删除 venv 来使用不同的 python 版本重新创建它:
<预><代码>>>>rm -rf <venv 路径>>>>pipenv --python <不同的python版本>可能会显示一条警告,指出 venv 的 python 版本与 Pipfile
中指定的版本不匹配,但据我所知,这只是一个警告.
https://github.com/pypa/pipenv/issues/1071
诗歌
Poetry 更适合此用例:可以并排创建多个 venv.要使用 pyenv
创建和使用新的 venv 开关 python 版本,然后创建一个新的 venv.
如果 python 版本与 pyproject.toml
中指定的版本不匹配,则会抛出错误,但是可以使用 semver 版本控制指定一系列 python 版本.
本地 venv
我更喜欢将 venv 安装在项目本地的 .venv
文件夹中,这与 npm
的工作方式类似,允许我删除该文件夹并重新安装如果发生任何奇怪的事情,或者(在 pipenv 的情况下)我想轻松更改我使用的 Python 版本.
pipenv
要启用此功能:设置以下环境变量.
<预><代码>>>>export PIPENV_VENV_IN_PROJECT=已启用";诗歌
可以使用以下命令启用此功能:
<预><代码>>>>诗歌配置 settings.virtualenvs.in-project true但要注意,这会改变poetry
的行为,将无法在不同版本的python之间使用快速切换:即使使用pyenv<切换python版本/code> 使用
poetry run
运行的所有命令都将使用驻留在本地目录中的 venv(及其相关的 Python 版本).
https://github.com/sdispater/poetry/issues/108
安装软件包
pipenv
软件包很容易安装并自动添加到 Pipfile
和 Pipfile.lock
文件中:
--dev
标志表示开发依赖.使用 pipenv install
时,默认不会安装开发依赖项.
也可以安装本地包,让您可以处理它们并立即查看您的更改:
<预><代码>>>>pipenv install -e <本地包的路径>诗歌
软件包很容易安装并自动添加到 pyproject.toml
和 poetry.lock
文件中:
--dev
标志表示开发依赖,使用poetry install
时默认不会安装开发依赖,发布时不会添加到包中.
也可以安装本地包,让您可以处理它们并立即查看您的更改:
<预><代码>>>>诗歌添加 --path <本地包的路径><包名>不确定为什么需要包的名称,因为它应该已经由本地包定义了.此外,作者似乎不相信一般链接本地包(https://github.com/sdispater/poetry/issues/34),因此随着时间的推移,此功能可能会被遗忘.
运行脚本
明确地说,我指的是 npm
所谓的脚本,它与 setup.py
文件中指定的脚本不同.
在开发时,有时为难以记住的命令设置快捷方式很有用,例如运行目录中每个测试文件的命令是:
<预><代码>>>>python -m unittest discover -s拥有这些命令的快捷方式会方便得多.
pipenv
支持此功能:将以下内容放入Pipfile
:
[脚本]test = "pipenv run python -m unittest discover -s tests -p '*_test.py'";
诗歌
不支持,将来不太可能添加:https://github.com/sdispater/poetry/pull/591#issuecomment-504762152
发布到 PyPi
最好能够在不制作额外的 setup.py
文件的情况下发布到 PyPi,如果发布包所需的所有信息都包含在包管理文件中,这将是可能的.
pipenv
据我所知,这就是 pipenv 名声不佳的地方.setup.py
文件仍然需要发布到 PyPi 并且不,它们不会自动填充来自 Pipfile
的依赖项.
推荐的方法是在发布时手动复制依赖项,或者让 Pipfile 安装 setup.py
文件中列出的依赖项,但是,setup.py
在运行 pipenv install
时不会自动更新.
如果你真的希望你的 Pipfile
依赖于你的 setup.py
文件,它是这样完成的:
https://github.com/pypa/pipenv/issues/2805、https://realpython.com/pipenv-guide/#yes-i-need-to-distribute-my-code-as-a-package, https://github.com/pypa/pipenv/issues/209
糟糕!
所以理想情况下,我们希望从 Pipfile
派生一个 setup.py
文件:
我发现了两个声称可以做到这一点的现有软件包:
https://pypi.org/project/pipenv-tools/- 但是已经两年没有更新了,
src
目录下没有代码,我无法让它工作.https://pypi.org/project/pipenv-setup/- 但它同步
Pipfile.lock
而不是Pipfile
,这是一种反模式.锁定文件旨在创建可重现的环境,它对于setup.py
的使用过于严格(例如,不允许更新依赖项).出于这个原因,我什至没有尝试使用它.
我的解决方案:
我很快编写了一个包,它生成一个 install_requires.py
文件,该文件可以导入到 setup.py
文件中:https://pypi.org/project/pipenv2setup/(在 Windows 上未经测试).
发布pipenv项目时如何使用包的例子,请看这个github repo:
https://github.com/alanbacon/pipenvExample
诗歌
使用诗歌发布您的包真的很容易,您根本不需要 setup.py
文件.只需运行:
发布的包可以使用 pip
安装,而不仅仅是 poetry
的其他实例.
有关如何从使用 setup.py
迁移到纯 pyproject.toml
文件的信息,请参阅此处:https://johnfraney.ca/posts/2019/05/28/create-publish-python-包诗/
IntelliJ 或 Pycharm 集成
pipenv
Pycharm 可以使用 Piplock
文件检测 venv,但是使用 Pycharm 接口添加新包不会修改 Piplock
文件.
诗歌
在撰写本文时,Pycharm 似乎不知道任何诗歌虚拟环境或似乎以任何方式解析 pyproject.toml
文件.
关于诗歌的其他要点
服务器
在poetry
中,你必须使用semver指定python和包的版本(必须使用~
和^
,而不是>=
或 <
) https://nodesource.com/blog/semver-tilde-and-caret.
越野车
poetry
使用 python 运行,但不适用于旧版本的 python.所以要为旧版本的 python 开发:一些命令必须在 pyenv
设置为 >3.6 的情况下运行,但是 pyenv
需要切换回旧版本创建 venv 的版本.venvs 似乎也必须大于 3.5.https://github.com/sdispater/poetry/issues/1223
也不确定 poetry
的 Windows 兼容性.
结论
对我来说 poetry
和 pipenv
之间的主要区别在于它们对 pyenv
的使用以及它们的发布能力(或缺乏)直接到 PyPi
.诗歌
中也缺少脚本,我个人觉得这很令人沮丧.
我发现在使用 poetry
时,使用 pyenv
在 python 环境之间有更多的切换.虽然目前这可以通过使用本地安装 venv 来缓解.我知道这限制了我在不同的 Python 环境中快速测试我的代码的能力,但还有其他工具,例如 tox
可以做到这一点.
使用poetry
发布到PyPi
非常简单,我在一行(上)中进行了解释.使用 pipenv
发布到 PyPi
是一个雷区,为了解释这一点,我必须链接到整个 git 存储库(如上).
How do the main features of npm
compare with pip
, pipenv
and poetry
package managers? And how do I use those features of pipenv
or poetry
?
This could primarily help someone transitioning from being JavaScript developer to a python developer.
I've never used used rubygems but it may also be useful to compare the main features of that to the main python package mangers. To help anyone coming from a ruby background.
Overview
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 | ✗ |
- Directly publishing with
pipenv
is possible if using a 3rd party dev dependency, and a script to tie it all together, see below.
Disclaimer: I only have experiences of these packages managers on 'NIX systems (OSX in particular), pipenv
markets itself as treating Windows is a first class citizen, I'm not sure how this works without pyenv
, which is not available on Windows as far as I am aware.
Basic Usage
pipenv:
To get the most out of pipenv
, pyenv
should be installed. pipenv
will be able to detect and use any version of python installed with pyenv
, even if it is not activated. For example if a Pipfile
has listed python 3.4 as a requirement: to successfully run pipenv install
, pyenv install 3.4.0
should be run first.
To create a new Pipfile
and venv (using python 3.7.x):
>>> pipenv --python 3.7
Or to install dependencies from an existing Pipfile.lock
use the command below. This command can also be used to create a Pipfile
and venv (defaulting to the newest available python version).
>>> pipenv install
To run commands within the created venv:
>>> pipenv run <script or command>
e.g
>>> pipenv run python main.py
poetry
Poetry still uses pyenv
but in a different way: The version of python you wish to use must be activated before calling poetry install
or poetry run
.
A pyproject.toml
can be created using:
>>> poetry init
or a full directory structure can be created using:
>>> poetry new <dir>
Before we can install we must activate a version of python that matches what is specified in the pyproject.toml
file.
>>> pyenv global <python version specified in pyproject.toml>
Now we are able to create the venv using the command below, if a poetry.lock
file is present it will install all the dependencies listed in it.
>>> poetry install
To run commands within the created venv:
>>> poetry run <command>
If we change the global python version using pyenv
we will no longer be able to run commands in the created venv. There is an exception to this if we use a locally created venv, see below.
Running your code using different python versions
Sometimes it's good to check that your code will work on both python 3.7 and python 3.4. This is not something we can take for granted.
pipenv
Only possible by deleting the venv in recreating it using a different python version:
>>> rm -rf <path to venv>
>>> pipenv --python <different python version>
A warning will likely be displayed that the python version of the venv does not match the one specified in the Pipfile
, but as far as I can tell it is only a warning.
https://github.com/pypa/pipenv/issues/1071
poetry
Poetry is much better suited to this use case: Multiple venvs can be created side by side. To create and use a new venv switch python versions using pyenv
then create a new venv.
>>> pyenv global <different python version>
>>> poetry install
An error will be thrown if the python version does not match the one specified in the pyproject.toml
however a range of python versions can be specified using semver versioning.
Local venv
I prefer my venv to be installed in a .venv
folder local to my project, this is similar to how npm
works and allows me to delete the folder and reinstall if anything strange happens or if (in the case of pipenv) I want to easily change which version of python I'm using.
pipenv
To enable this feature: set the following environment variable.
>>> export PIPENV_VENV_IN_PROJECT="enabled"
poetry
This feature can be enabled using the following command:
>>> poetry config settings.virtualenvs.in-project true
But beware that this will change the behavior of poetry
, it will no longer be possible to use quickly switch between different versions of python: Even if the python version is switched using pyenv
all commands run using poetry run
will use the venv (and its associated python version) that resides in the local directory.
https://github.com/sdispater/poetry/issues/108
Installing Packages
pipenv
Packages are easily installed and automatically added to the Pipfile
and Pipfile.lock
files using:
>>> pipenv install [--dev] <package name>
The --dev
flag indicates a development dependency. Development dependencies will not be installed by default when using pipenv install
.
Local packages can also be installed, allowing you to work on them and see your changes immediately:
>>> pipenv install -e <path to local package>
poetry
Packages are easily installed and automatically added to the pyproject.toml
and poetry.lock
files using:
>>> poetry add [--dev] <package name>
The --dev
flag indicates a development dependency, Development dependencies will not be installed by default when using poetry install
or added to the package when publishing.
Local packages can also be installed, allowing you to work on them and see your changes immediately:
>>> poetry add --path <path to local package> <name of package>
Not sure why the name of the package is needed, as it should already be defined by the local package. Also the author seems unconvinced about linking local packages in general (https://github.com/sdispater/poetry/issues/34) so this feature may get forgotten about over time.
Running Scripts
To be clear, I'm referring to what npm
calls scripts, which is different to the scripts specified inside a setup.py
file.
When developing it is sometimes useful to set up shortcuts for commands that are difficult to remember, for example the command for running every test file in a directory is:
>>> python -m unittest discover -s <test_folder> -p '*_test.py'
It is much more convenient to have a shortcut to these sorts of commands.
pipenv
This feature is supported: put the following into the Pipfile
:
[scripts]
test = "pipenv run python -m unittest discover -s tests -p '*_test.py'"
poetry
Not supported, and unlikely to be added in the future: https://github.com/sdispater/poetry/pull/591#issuecomment-504762152
Publishing to PyPi
It would be preferable to be able to publish to PyPi without crafting an additional setup.py
file, this would be possible if all the information needed to publish the package was contained within the package management files.
pipenv
As far as I can tell this is where pipenv gets its bad reputation. setup.py
files are still needed to publish to PyPi and no, they are not auto-populated with the dependencies from the Pipfile
.
The recommended approach is to either copy the dependencies over manually when publishing, or to get the Pipfile to install the dependencies listed in the setup.py
files, however, the setup.py
is not automatically updated when running pipenv install <package name>
.
If you really want your Pipfile
to depend on your setup.py
file, this is how it's done:
>>> pipenv install '-e .'
https://github.com/pypa/pipenv/issues/2805, https://realpython.com/pipenv-guide/#yes-i-need-to-distribute-my-code-as-a-package, https://github.com/pypa/pipenv/issues/209
Yuck!
So ideally we want to derive a setup.py
file from the Pipfile
:
I found two existing packages that claim to do this:
https://pypi.org/project/pipenv-tools/ - But it hasn't been updated in two years, there's no code in the
src
directory and I couldn't get it to work.https://pypi.org/project/pipenv-setup/ - But it syncs the
Pipfile.lock
instead of thePipfile
, this is an anti-pattern. The lock file is meant for creating a reproducible environment, it is overly restrictive (e.g. by not allowing updates to dependencies) to be used forsetup.py
. For this reason I didn't even try using it.
My Solution:
I quickly wrote a package that generates an install_requires.py
file that can be imported in a setup.py
file: https://pypi.org/project/pipenv2setup/ (it is untested on Windows).
For an example of how to use the package when publishing pipenv projects, see this github repo:
https://github.com/alanbacon/pipenvExample
poetry
Publishing your package using poetry is really easy, you do not need a setup.py
file at all. Simply run:
>>> poetry publish [--build] [--username <username>] [--password <password>]
The published package can be installed using pip
not just by other instances of poetry
.
For information about how to migrate from using a setup.py
to purely a pyproject.toml
file, see here: https://johnfraney.ca/posts/2019/05/28/create-publish-python-package-poetry/
IntelliJ or Pycharm integration
pipenv
Pycharm is able detect the venv by using the Piplock
files, however adding new packages using the Pycharm interface will not modify the Piplock
files.
poetry
At the time of writing Pycharm does not seem to be aware of any poetry virtual environments or appear to parse the pyproject.toml
file in any way.
Other Points about poetry
Semver
In poetry
you must specify versions of python and packages using semver (have to use ~
and ^
, not >=
or <
) https://nodesource.com/blog/semver-tilde-and-caret.
Buggyness
poetry
runs using python but doesn't work with older versions of python. So to develop for an older version of python: some commands have to be run with pyenv
set to >3.6, but then the pyenv
needs to be switched back to the older version to create the venv. It also appears that venvs have to be greater than 3.5.
https://github.com/sdispater/poetry/issues/1223
Also not sure about windows compatibility for poetry
.
Conclusion
To me the main differences between the poetry
and pipenv
lie in their usage of pyenv
and their abilities (or lack of) to publish straight to PyPi
. There is also the lack of scripts in poetry
which I personally find frustrating.
I find that when using poetry
there is a lot more switching between python environments using pyenv
. Although currently this can be mitigated by using a locally install venv. I know this limits my ability to quickly test my code in different python environments, but there are other tools such as tox
to do that.
Publishing to PyPi
using poetry
is so easy, I explained it in one line (above). Publishing to PyPi
with pipenv
is a minefield, to explain it I had to link to an entire git repo (above).
这篇关于npm、pip、pipenv 和诗歌包管理器的功能比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!