[英]Equivalent of `package.json' and `package-lock.json` for `pip`
Package managers for JavaScript
like npm
and yarn
use a package.json
to specify 'top-level' dependencies, and create a lock-file to keep track of the specific versions of all packages (ie top-level and sub-level dependencies) that结果被安装。
此外, package.json
允许我们区分顶级依赖项的类型,例如生产和开发。
另一方面,对于Python
,我们有pip
。 我想pip
等效于lock
文件将是pip freeze > requirements.txt
的结果。
但是,如果您只维护这个单一的requirements.txt
文件,则很难区分顶级和子级依赖项(您需要例如pipdeptree -r
来弄清楚这些)。 如果您想删除或更改顶级依赖项,这可能会非常痛苦,因为很容易留下孤立的包(据我所知, pip
pip uninstall
包时不会删除子依赖项)。
现在,我想知道:是否有一些约定可以处理不同类型的这些requirements
文件并使用pip
区分顶级和子级依赖项?
例如,我可以想象有一个requirements-prod.txt
只包含生产环境的顶级需求,作为package.json
的(简化)等效项,以及一个requirements-prod.lock
,其中包含 Z7148E62218F69393 的 Z71436CEDZD pip freeze
,并充当我的lock
文件。 此外,我可以有一个requirements-dev.txt
用于开发依赖项,依此类推。
我想知道这是否是通往 go 的方法,或者是否有更好的方法。
ps 可以对conda
的environment.yml
提出相同的问题。
今天至少有三个不错的选择:
pipenv
使用Pipfile
和Pipfile.lock
方式与您描述类似 JavaScript 文件的方式类似。 pipenv
是一个比pip
更“大”的工具,因为它还创建和管理 virtualenvs。
这可能是当今最流行的选项,它几乎肯定会在许多开发人员的工作流程中取代pip
。
poetry
使用pyproject.toml
和poetry
poetry.lock
文件,也类似于您描述 JavaScript 文件的方式。
pip-tools
提供了pip-compile
和pip-sync
命令。 在这里, requirements.in
列出您的直接依赖项,通常具有松散的版本约束, pip-compile
从您的.in
文件生成锁定的requirements.txt
文件。
就个人而言,我喜欢这个工具,因为它向后兼容(生成的requirements.txt
可以由pip
处理)并且pip-sync
工具确保 virtualenv 与锁定的版本完全匹配,删除不在“锁定”中的内容文件。
我有同样的问题,我想出了一个更通用和简单的解决方案。 我对所有显式依赖项和requirements.lock
使用众所周知的requirements.txt
作为所有包的列表,包括子依赖项。
I personally like to manage python
, pip
and setuptools
via the distributions builtin package manager and install pip dependencies inside a virtual environment .
通常你会开始安装所有直接需要的依赖项。 这也将引入所有子依赖项。 如果您不使用虚拟环境,请确保添加--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,我建议您运行以下命令。 请注意,如果它们已经被另一个 package 满足,它将不包括子依赖项。 这意味着如果请求已经被另一个 package 满足,则requests
将不会包含在列表中。 如果您的脚本明确依赖于这样的 package,您可能仍想手动添加它。
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
最后,我们可以将 output 的所有依赖项添加到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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.