Pip freeze仅列出项目需求

96

当我运行pip freeze > requirements.txt时,似乎包括了所有已安装的软件包。这个看起来是符合文档的行为。

然而,我做错了什么,因为这现在包括一些像 Django 这样与 Django 无关的项目。

我该如何获得只针对此项目的要求文件?或者在将来,我该如何使用virtualenv安装适用于此项目的软件包。我认为我漏掉了关于virtualenv的一些东西。


9
pip无法理解你的项目与Django等框架没有业务关联。因此,通常你需要创建一个隔离的虚拟环境,不允许访问系统的site-packages,并使用--isolated标志运行pip来忽略PYTHONPATH中的内容。当然,除了项目所需的包之外,你不应该将其他包安装到该环境中。 - Konstantin
1
@Alik 好的,我就怕这个。我会稍后研究创建虚拟环境。如果你想把这作为实际答案提交,我会接受它。 - Marshall Davis
12个回答

145

pipreqs可以为特定项目解决难题。只需执行以下操作:


pip install pipreqs
#then
pipreqs path/to/project

Github页面


3
我可能没有正确理解,但是这是否会混淆install_requires和requirement.txt? requirement.txt旨在是完整和详尽的,而install_requires旨在是最少的。https://packaging.python.org/discussions/install-requires-vs-requirements/ - onesiumus
@Daniel Maksimovich,我认为你的意思是命令不会输出所有应该在requirements.txt中的“desired - pinned”包。这是正确的,因为该软件包根据目标目录中文件中的导入来嗅探要求。但它不会混淆两者。无论如何,“install requires”将确保重用生成的requirements.txt将安装可能被忽略的所有要求。 - unlockme
这个操作生成了一个文件,但是其中没有原Python文件中的任何包,比如 google-cloud-storage - Zimano

32

我尝试过pipreqspigar,发现pigar更好,因为它还生成有关其使用位置的信息,并且具有更多选项。


除此之外,pipreqs 对 mysql-connector 和 hydra 的处理有误。在我看来,这是相当愚蠢的错误。 - Qiulang
1
Pipreqs有点老旧并且存在一些bug。 - Leo Lee
Pigar 可以工作,但请注意,仅在命令行上调用 pigar 将覆盖您的 requirements.txt 文件。 不需要使用 > requirements.txt - rocksNwaves

19

我使用这个命令:

编辑:感谢Addisson Klinke的建议

pip freeze -r requirements.txt | grep -B100 "pip freeze" | grep -v "pip freeze"

pip freeze -r requirements.txt | sed '/freeze/,$ d'

当我运行pip freeze -r requirements.txt时,输出结果类似于:

APScheduler==3.2.0
Eve==0.6.4
Eve-Elastic==0.3.8
## The following requirements were added by pip freeze:
arrow==0.8.0
Cerberus==0.9.2
我有一个类似这样的需求文件。
APScheduler
Eve
Eve-Elastic

我得到了这个输出并使用sed来删除我不想要的依赖关系。

首先将此输出到文件中。

pip freeze -q -r requirements.txt | sed '/freeze/,$ d' > requirements-froze.txt 

这将仅输出带有版本号的库

APScheduler==3.2.0
Eve==0.6.4
Eve-Elastic==0.3.8

然后替换要求文件

mv requirements-froze.txt requirements.txt 

我需要进一步研究这个问题,但我相信所有的要求都是通过 pip freeze 添加的,这意味着被搜索的行应该是第一行。 - Marshall Davis
1
谢谢分享 pip freeze -r 选项 - 我不知道这个!我认为 grep 管道有点冗长/脆弱 - 更好的方法可能是 pip freeze -r requirements.txt | sed '/freeze/,$ d。这将删除冻结行和所有后续行,直到列表结束。 - Addison Klinke
1
如果你有像 some-package[some-extra] 这样的东西,那么这个会出错,因为额外的包在 sed 之后没有被包含在 about 中。 - The Fool
你能给一个例子吗,@TheFool? - undefined
@LuisComS,我觉得我的评论很清楚。它包含一个例子。不确定你是否熟悉那种语法。你可以试试flask[async],例如。https://flask.palletsprojects.com/en/2.3.x/async-await/ - undefined

12
我建议使用官方的 pip freeze > requirements.txt (文档),而不是其他答案中提到的两个替代工具 pigarpipreqs,因为 pip freeze 列出了 有效的软件包名称

截至 2022 年 2 月的三种工具的比较不完整

标准 \ 工具 pip freeze > requirements.txt pigar pipreqs
名称不匹配 (1) my-package==1.0.0 模块 my_package == 1.0.0 模块 my_package==1.0.0
模块重载 (2) 所有软件包 my-package1==1.0.0my-package2==2.0.0 顶级模块 (版本显示为0.0.0) my==0.0.0
仅显示直接使用的软件包
最小内容

(1) 模块和软件包名称可能不匹配,例如 my-package(软件包名称)与 my_package(模块名称)。

(2) 可能会有多个使用同一顶级文件夹的软件包,例如安装在 my/package1my/package2 下的包名分别为 my-package1my-package2,可以通过 Python 命令 import my.package1import my.package2 导入。请注意,pipreqs 对不存在的软件包 my 注明版本 0.0.0。

我知道这些都是非常特殊的情况,但我希望提供这个概述可以帮助人们了解限制并避免可能的错误。


7
pip install pipreqs 
pipreqs>requirements.txt

那很容易解决

2

1

有一个在Windows和Lunix上都适用的软件包Pipdeptree,对我来说很好用。

安装后,您可以使用Pipdeptree仅生成顶级软件包的requirements.txt文件。

Windows:

pipdeptree -f --warn silence | findstr  /r  "^[a-zA-Z0-9\-]" > requirements.txt

Linux:

pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\-]+' > requirements.txt 

1
如果您正在使用Linux,则可以使用sed进行操作。 pip freeze | sed 's/==.*$/''/' > requirements.txt

1

我遇到了与 pip freeze 相同的问题。在我的情况下,问题是我在没有激活项目的虚拟环境的情况下运行了 pip freeze。我激活了虚拟环境,然后 pip freeze > requirements.txt 就正常工作了。

所以确保通过在 Windows 上运行 <virtualenv 文件夹名称>\Scripts\activate 或在 Linux 上运行 source <virtualenv 文件夹名称>\bin\activate 来激活你的项目虚拟环境。

如果 virtualenv 具有全局访问权限,你应该使用 -l--local 选项运行 pip freeze,即 pip freeze -l,根据 pip freeze 文档 的说明:

-l, --local
如果在具有全局访问权限的虚拟环境中,不输出全局安装的包。


1

在激活virtualenv后,执行python -E -m pip freeze命令。根据python --help的解释,-E标志表示忽略PYTHON*环境变量(例如PYTHONPATH),因此pip不会访问全局的site-packages


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接