我应该如何生成 requirements.txt? Pip Freeze 不是一个好方法

How should I generate requirements.txt? Pip Freeze not a good way

我应该如何为 Python 个项目生成 requirements.txt?

这是我在使用 pip freeze 时遇到的问题。假设我的包P需要A,B,C。假设C是一个库,导入了X,Y,Z,但是P只需要X。那么如果I:

1) Install A
2) Install B
3) Install C, which installs X, Y, Z
4) Do a pip freeze into P's requirements.txt 

然后 P 的 requirements.txt 将如下所示:

1) A
2) B
3) C
4) X
5) Y
6) Z

但是我的 Python 安装 P 到 运行 实际上不需要 Y 和 Z。

许多答案假设 Y 必须是。但是,python 是一种动态语言。通常情况下,例如 C 是一个巨大的库,它使用 numpypandas 来实现 某些 功能;但 P 不调用库的那部分 - 在这种情况下,如果我知道 P 需要 C 的哪些部分,我 真的 不需要将它们拉入。如果所有的图书馆都是“小”的;这种情况很少见,但是有很多“厨房水槽”库。

据我所知,运行宁 pip freeze 生成 P 的需求将向您显示依赖项的所有依赖项,因此是 P 的实际依赖项的超集。

virtualenv 的目的是完全控制 安装的包。

假设您只列出了 A、B、C 和 X。每次您从该需求文件创建一个新的 virtualenv 时,您将获得最新版本的 Y 和 Z。这有几个问题:

  1. 你不知道你没有使用 Y:对于一个足够复杂的项目,几乎不可能审计每个代码路径以确保 C 永远不会调用 Y。你不再只是担心您自己的代码;你也在担心 C 的代码。这只是无法扩展。
  2. 即使您只是导入 Y,您也在使用它:Python 允许在导入时执行任意代码。新版本的 Y 可以在导入时做各种令人讨厌的事情,例如打印到标准输出、猴子修补 X 或任何您能想到的事情。一个设计良好的 Y 不应该 做这些事情,但是你会发现 PyPI 上包的质量变化很大。
  3. Y 的新版本可以引入新的依赖项:如果你包含 Y 的新版本,你最终可能会将包 W 添加到你的 virtualenv 中,因为新版本Y 需要它。随着更多包的添加,前两个问题更加严重。更糟糕的是,您可能会发现 Y 的新版本依赖于 X 的更新版本,在这种情况下您不会得到您真正想要的包。
  4. 生成已知良好的配置更为重要pip freeze 并非旨在找出最低要求。它旨在支持将完整的应用程序一致地部署到许多不同的环境。这意味着它会谨慎行事,并列出 一切 可能合理地影响您的项目。

出于这些原因,您不应尝试从需求文件中删除 Y 和 Z。

有一个名为 pipreqs 的 python 模块。它根据项目中的导入生成 requirements.txt。

  1. 安装 pipreqs 库(例如 conda install -c conda-forge pipreqs
  2. 将目录更改为项目文件夹 (cd your/repository)
  3. 运行命令pipreqs --force

或者只是 pipreqs --force your/repository.

在官方来源中查看更多信息: https://pypi.org/project/pipreqs/

我已经在另一个 Whosebug 中回答了这个问题 post where I recommended using pip-compile from pip-tools