pipenv 和poetry 两个最大的好处是依赖性锁定和哈希检查。依赖性锁定意味着你可以指定你的代码所需要的直接依赖,例如,celery==4.4.* ,工具将锁定,不仅是celery 到一个特定的版本,而且还有由celery 拉入的每一个依赖。 哈希检查确保你下载的包与第一次下载时的包的哈希值相匹配。这确保了当celery (或其任何依赖关系)安装在不同的系统上时,它们与开发者建立时的文件哈希值相同。如果软件包在两次安装之间以某种方式被篡改,哈希值检查将失败,防止新的(和潜在的恶意)软件包被安装。
这两个特点的结合使你的项目安装具有确定性:给定相同的需求/锁定文件,你将总是得到相同的软件包安装。这可以防止当依赖关系在开发人员的机器、CI和部署之间的代码下转移时出现的各种问题。与我们以前管理依赖关系的方式相比,这是一个巨大的改进。
Pipenv 和 有许多其他的功能,但我发现自己很少使用它们。管理Python虚拟环境很好,但是对于有经验的Python开发者来说,在安装项目之前跳过 ,并不能改变游戏规则。我对 的经验有限,但在我们使用它的项目中, 的性能和边缘案例的错误一直是一个经常性的痛点。poetry python -m venv .venv poetry pipenv
用 pip-compile 锁定依赖关系
如果你愿意放弃铃铛和花哨的东西,pip-compile (由 pip-tools)是一个可行的替代方案。它为你的依赖关系提供了锁定和哈希钉的功能。一旦安装,你通常会创建一个requirements.in 文件。这是你定义你的项目的顶级依赖的地方(类似于pipenv的Pipfile 或pyproject.toml in poetry)。一个基本的例子可能是这样的。
Django==2.2.*
psycopg2
celery>4.4
要 "锁定 "这些依赖关系,你可以运行。
pip-compile --generate-hashes --output-file=requirements.txt requirements.in
这将生成包含所有依赖关系的标准requirements.txt 文件,并包括由PyPI提供的软件包散列值。下面是该文件的一行。
pytz==2019.3 \
--hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \
--hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be \
# via django
注意我们的requirements.in 中没有pytz ,但它被包含在requirements.txt 中,因为它是django 所需要的(pip-compile 很好地在文件中输出)。
如果你的项目使用了Makefile ,这个工作流程就很适合它。下面将允许你运行make requirements.txt ,如果且仅当requirements.in 文件在上次生成requirements.txt 后有变化时,它将被更新。
requirements.txt: requirements.in
pip-compile --upgrade --generate-hashes --output-file=$@ requirements.in
pip-compile 也提供了选择性升级个别软件包的选项,其 参数--upgrade-package 中提到了。 README.md
安装依赖项
安装依赖项的方法很简单。
pip install -r requirements.txt
你也可以使用pip-sync (包含在pip-tools 中)将现有的虚拟环境与requirements.txt 中存在的任何东西进行协调。这不仅可以根据需要安装/升级软件包,还可以删除不再存在于requirements.txt 中的软件包。
pipenv 和 在 Python 社区中得到了很多关注,这也是理所当然的。它们是伟大的项目,对开发者来说肯定是挠痒痒的。也就是说,如果你只是在寻找处理依赖性管理的东西, 可能就是你需要的全部。poetry pip-tools