`pip` 等效于 `package.json' 和 `package-lock.json`

djv*_*jvg 14 python dependencies pip requirements.txt conda

包管理器JavaScript喜欢npmyarn使用 apackage.json来指定“顶级”依赖项,并创建一个锁定文件来跟踪作为结果安装的所有包(即顶级子级依赖项)的特定版本。

此外,package.json允许我们区分顶级依赖项的类型,例如productiondevelopment

对于Python,另一方面,我们有pip。我想pip相当于一个lock-file 将是pip freeze > requirements.txt.

但是,如果您只维护这个单个requirements.txt文件,则很难区分顶级和子级依赖项(例如pipdeptree -r,您需要弄清楚这些)。如果您想删除或更改顶级依赖项,这可能会很痛苦,因为很容易留下孤立的包(据我所知,当您创建一个包时,pip 不会删除子依赖项pip uninstall)。

现在,我想知道:是否有一些约定来处理这些requirements文件的不同类型并区分顶级和子级依赖关系pip

例如,我可以想象有 arequirements-prod.txt只包含生产环境的顶级要求,作为 , 的(简化)等价物package.json,而 arequirements-prod.lock包含 , 的输出pip freeze,并充当我的 -lock文件。此外,我可以有一个requirements-dev.txt用于开发的依赖项,等等。

我想知道这是要走的路,还是有更好的方法。

ps 同样的问题可以问condaenvironment.yml

Chr*_*ris 14

今天至少有三个不错的选择:

  1. pipenv使用PipfilePipfile.lock您描述类似 JavaScript 文件的方式类似。pipenv是一个“更大”的工具pip,因为它还创建和管理 virtualenvs。

    这可能是当今最流行的选项,并且几乎肯定会pip在许多开发人员的工作流程中取而代之。

  2. poetryusespyproject.tomlpoetry.lockfiles,也类似于您描述 JavaScript 文件的方式。

  3. pip-tools提供pip-compilepip-sync命令。在这里,requirements.in列出您的直接依赖项,通常具有松散的版本约束,并从您的文件pip-compile生成锁定文件。requirements.txt.in

    就个人而言,我喜欢这个工具,因为它向后兼容(生成的requirements.txt可以由 处理pip)并且该pip-sync工具确保 virtualenv 与锁定版本完全匹配,删除不在“锁定”文件中的内容。

  • 感谢您的精彩回答,它让我看到了[这篇有趣的帖子](https://nvie.com/posts/better-package-management/)。然而,我对采用“pipenv”犹豫不决,因为它使用“virtualenv”而不是“conda”,因为我真的很喜欢(并依赖)“conda”管理“Python”版本的能力。 (2认同)