JavaScript
的包管理器(如npm
和yarn
)使用package.json
来指定“顶层”依赖项,并创建一个锁档来跟踪结果安装的所有包的特定版本(即顶层和子级依赖项)。
此外,package.json
允许我们区分顶级依赖项的类型,例如生产和开发。
另一方面,对于Python
,我们有pip
。我认为pip
等价于lock
-file将是pip freeze > requirements.txt
的结果。
但是,如果您只维护这个单一的requirements.txt
文件,那么很难区分顶级依赖项和子级别依赖项(例如,需要pipdeptree -r
来确定这些依赖项)。如果您想要删除或更改顶级依赖项,这可能是一个真正的痛苦,因为很容易将其留给孤立的包(据我所知,pip
不移除子依赖项。,当您pip uninstall
一个包时)。
现在,我想知道:是否有处理这些requirements
文件的不同类型的约定,以及用pip
区分顶层和子级别的依赖关系?
例如,我可以想象有一个requirements-prod.txt
,它只包含生产环境的顶级需求,作为package.json
的(简化)等价物;requirements-prod.lock
,它包含pip freeze
的输出,充当my lock
-file。此外,我还可以有一个用于开发依赖的requirements-dev.txt
,等等。
我想知道这是否可行,还是有更好的办法。
附注:同样的问题也可以被问到conda
的environment.yml
。
发布于 2018-10-05 04:34:46
今天至少有三个很好的选择:
package.json
和lock文件在JavaScript世界中的工作方式大同小异。
这是我现在更喜欢的解决方案。Pipfile.lock
,也很像描述JavaScript文件。诗歌和Pipenv所做的不仅仅是依赖管理。此外,他们还为您的项目创建和维护虚拟环境。
pip-tools
提供pip-compile
和pip-sync
命令。在这里,requirements.in
列出了您的直接依赖项,通常带有松散的版本约束,而pip-compile
从您的.in
文件中生成锁定的requirements.txt
文件。
这曾经是我最喜欢的解决方案。它是向后兼容的(生成的requirements.txt
可以由pip
处理),并且pip-sync
工具确保虚拟主机与锁定版本完全匹配,删除了“锁”文件中没有的内容。发布于 2022-09-09 23:10:10
我有同样的问题,我想出了一个更通用、更简单的解决方案。我将众所周知的requirements.txt
用于所有显式依赖项,并使用requirements.lock
作为包括子依赖项在内的所有包的列表。
我个人喜欢通过发行版内置包管理器管理python
、pip
和setuptools
,并在虚拟环境中安装pip依赖项。
通常,您将开始安装所有直接需要的依赖项。这也将引入所有的子依赖关系。如果您没有使用虚拟环境,请确保添加--user
标志。
# If you already have a requirements file
pip3 install -r requirements.txt
# If you start from scratch
pip3 install <package>
如果您想升级您的软件包,请使用这里也有多个选项。因为我使用的是虚拟环境,所以我将总是更新所有的包。但是,您可以只更新直接需求。如果他们需要更新他们的依赖关系,这些也将被拉进来,其他一切都将保持不变。
# Update all outdated packages (excluding pip and setuptools itself)
pip3 install -r <(pip3 list --outdated --format freeze --exclude pip setuptools | cut -d '=' -f1) --upgrade
# Update explicitly installed packages, update sub dependencies only if required.
pip3 install -r <(cut -d '=' -f1 requirements.txt) --upgrade
现在我们来看一个棘手的部分:保存我们的需求文件。确保前面的需求文件被签入git,因此如果有任何问题,您就有一个备份。
请记住,我们希望区分显式安装的包(requirements.txt
)和包,包括它们的依赖项(requirements.lock
)。
如果您还没有设置requirements.txt,我建议运行以下命令。注意,如果子依赖项已经被另一个包满足,则不包含子依赖项。。这意味着如果requests
已经被另一个包所满足,它将不会被包括在列表中。如果脚本显式地依赖于这样的包,您可能仍然希望手动添加该包。
pip3 list --not-required --format freeze --exclude pip --exclude setuptools > requirements.txt
如果您已经有了一个requirements.txt
,您可以使用这个sed的诡计来更新它。这将使所有子依赖项保留在外部,我们将只在下一步的requirements.lock
中包含这些依赖项。
pip3 freeze -r requirements.txt | sed -n '/## The following requirements were added by pip freeze:/q;p' | sponge requirements.txt
最后,我们可以将所有依赖项输出到requirements.lock
文件中,这将是我们列出的所有包和版本的完整列表。如果我们有问题要重现一个问题,我们总是可以回到这个锁文件,并运行我们的代码与以前工作的依赖关系。
# It is important to use the -r option here, so pip will differenciate between directly required packages and dependencies.
pip3 freeze -r requirements.txt > requirements.lock
https://stackoverflow.com/questions/52665596
复制相似问题