我应该如何生成 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 是一个巨大的库,它使用 numpy
或 pandas
来实现 某些 功能;但 P 不调用库的那部分 - 在这种情况下,如果我知道 P 需要 C 的哪些部分,我 真的 不需要将它们拉入。如果所有的图书馆都是“小”的;这种情况很少见,但是有很多“厨房水槽”库。
据我所知,运行宁 pip freeze
生成 P 的需求将向您显示依赖项的所有依赖项,因此是 P 的实际依赖项的超集。
virtualenv 的目的是完全控制 安装的包。
假设您只列出了 A、B、C 和 X。每次您从该需求文件创建一个新的 virtualenv 时,您将获得最新版本的 Y 和 Z。这有几个问题:
- 你不知道你没有使用 Y:对于一个足够复杂的项目,几乎不可能审计每个代码路径以确保 C 永远不会调用 Y。你不再只是担心您自己的代码;你也在担心 C 的代码。这只是无法扩展。
- 即使您只是导入 Y,您也在使用它:Python 允许在导入时执行任意代码。新版本的 Y 可以在导入时做各种令人讨厌的事情,例如打印到标准输出、猴子修补 X 或任何您能想到的事情。一个设计良好的 Y 不应该 做这些事情,但是你会发现 PyPI 上包的质量变化很大。
- Y 的新版本可以引入新的依赖项:如果你包含 Y 的新版本,你最终可能会将包 W 添加到你的 virtualenv 中,因为新版本Y 需要它。随着更多包的添加,前两个问题更加严重。更糟糕的是,您可能会发现 Y 的新版本依赖于 X 的更新版本,在这种情况下您不会得到您真正想要的包。
- 生成已知良好的配置更为重要:
pip freeze
并非旨在找出最低要求。它旨在支持将完整的应用程序一致地部署到许多不同的环境。这意味着它会谨慎行事,并列出 一切 可能合理地影响您的项目。
出于这些原因,您不应尝试从需求文件中删除 Y 和 Z。
有一个名为 pipreqs 的 python 模块。它根据项目中的导入生成 requirements.txt。
- 安装
pipreqs
库(例如 conda install -c conda-forge pipreqs
)
- 将目录更改为项目文件夹 (
cd your/repository
)
- 运行命令
pipreqs --force
或者只是 pipreqs --force your/repository
.
在官方来源中查看更多信息:
https://pypi.org/project/pipreqs/
我已经在另一个 Whosebug 中回答了这个问题 post where I recommended using pip-compile
from pip-tools
我应该如何为 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 是一个巨大的库,它使用 numpy
或 pandas
来实现 某些 功能;但 P 不调用库的那部分 - 在这种情况下,如果我知道 P 需要 C 的哪些部分,我 真的 不需要将它们拉入。如果所有的图书馆都是“小”的;这种情况很少见,但是有很多“厨房水槽”库。
据我所知,运行宁 pip freeze
生成 P 的需求将向您显示依赖项的所有依赖项,因此是 P 的实际依赖项的超集。
virtualenv 的目的是完全控制 安装的包。
假设您只列出了 A、B、C 和 X。每次您从该需求文件创建一个新的 virtualenv 时,您将获得最新版本的 Y 和 Z。这有几个问题:
- 你不知道你没有使用 Y:对于一个足够复杂的项目,几乎不可能审计每个代码路径以确保 C 永远不会调用 Y。你不再只是担心您自己的代码;你也在担心 C 的代码。这只是无法扩展。
- 即使您只是导入 Y,您也在使用它:Python 允许在导入时执行任意代码。新版本的 Y 可以在导入时做各种令人讨厌的事情,例如打印到标准输出、猴子修补 X 或任何您能想到的事情。一个设计良好的 Y 不应该 做这些事情,但是你会发现 PyPI 上包的质量变化很大。
- Y 的新版本可以引入新的依赖项:如果你包含 Y 的新版本,你最终可能会将包 W 添加到你的 virtualenv 中,因为新版本Y 需要它。随着更多包的添加,前两个问题更加严重。更糟糕的是,您可能会发现 Y 的新版本依赖于 X 的更新版本,在这种情况下您不会得到您真正想要的包。
- 生成已知良好的配置更为重要:
pip freeze
并非旨在找出最低要求。它旨在支持将完整的应用程序一致地部署到许多不同的环境。这意味着它会谨慎行事,并列出 一切 可能合理地影响您的项目。
出于这些原因,您不应尝试从需求文件中删除 Y 和 Z。
有一个名为 pipreqs 的 python 模块。它根据项目中的导入生成 requirements.txt。
- 安装
pipreqs
库(例如conda install -c conda-forge pipreqs
) - 将目录更改为项目文件夹 (
cd your/repository
) - 运行命令
pipreqs --force
或者只是 pipreqs --force your/repository
.
在官方来源中查看更多信息: https://pypi.org/project/pipreqs/
我已经在另一个 Whosebug 中回答了这个问题 post where I recommended using pip-compile
from pip-tools