查找所有使用easy_install/pip安装的软件包?

426

有没有一种方法可以找到所有使用easy_install或pip安装的Python PyPI包?我的意思是,排除使用发行版工具(在这种情况下是Debian上的apt-get)安装的所有内容。


19个回答

403

92
从版本1.3开始,“pip list”已被添加。请参阅我的下面的答案和这里的文档:http://www.pip-installer.org/en/latest/usage.html#pip-list - keybits
7
列出和冻结输出不同的格式(截至撰写本文时)。冻结输出可用于重新创建环境:http://docs.python-guide.org/en/latest/dev/virtualenvs/#other-notes - Tom Saleeba
23
pip freezepip list 命令会列出所有内容,它们不会排除那些非通过 pip 安装的软件包。 - Eliad
我也发现在脚本中使用 pip freeze 是可靠的,而 pip list 在与管道一起使用时会生成意外的错误。 - Dale C. Anderson
3
新的 pip list -lpip list --local 是最好的答案,参见 https://dev59.com/2Ww15IYBdhLWcg3wcrdC#43012269 由 @MJB 提供。 - jmuc
这并没有回答问题:列出由PIP安装的软件包,但不包括与发行版软件包一起安装的软件包。 - Luis Vazquez

270

4
在 Gentoo 上,这将列出所有软件包,即使是通过pip以外的其他方式安装的软件包也会列出。这样是否确实排除了其他系统上非pip安装的模块,正如问题所要求的那样? - jlh
请注意,这与 pip freeze 稍有不同。 - s g
4
pip list --user 只会显示用户安装的软件包,而排除系统范围内的软件包。 - Jacob Hume
@JacobHume,--user标志将使pip安装到用户安装目录。它不会列出使用sudo pip install packagexyz安装的内容。 - Capi Etheriel

139

如果有人想知道,你可以使用“pip show”命令。

pip show [options] <package>

这将列出给定软件包的安装目录。


28

开始:

$ pip list

列出所有软件包。一旦找到所需的软件包,请使用:

$ pip show <package-name>

这将向您显示有关此软件包的详细信息,包括其文件夹。如果您已经知道软件包名称,则可以跳过第一部分。

单击此处以获取有关pip show的更多信息,并单击此处以获取有关pip list的更多信息。

示例:

$ pip show jupyter
Name: jupyter
Version: 1.0.0
Summary: Jupyter metapackage. Install all the Jupyter components in one go.
Home-page: http://jupyter.org
Author: Jupyter Development Team
Author-email: jupyter@googlegroups.org
License: BSD
Location: /usr/local/lib/python2.7/site-packages
Requires: ipywidgets, nbconvert, notebook, jupyter-console, qtconsole, ipykernel    

在我看来,最佳答案是:如果我知道包的名称,那么使用pip show my_package非常简单和快速。甚至不需要使用pip list,而且freeze可能需要很长时间,我还需要过滤掉我不关心的内容。 - ChuckZ

26
如果Debian在pip install默认目标方面的行为与最近的Ubuntu版本相似,那么它很容易解决:它会安装到/usr/local/lib/而不是/usr/libapt默认目标)。请参考https://askubuntu.com/questions/173323/how-do-i-detect-and-remove-python-packages-installed-via-pip/259747#259747 我是一名ArchLinux用户,在使用pip时遇到了同样的问题。以下是我在Arch中解决此问题的方法。
find /usr/lib/python2.7/site-packages -maxdepth 2 -name __init__.py | xargs pacman -Qo | grep 'No package'

关键在于/usr/lib/python2.7/site-packages,这是pip安装的目录,可能会有所不同。pacman -Qo是Arch的包管理器检查文件所有权的方式。当没有软件包拥有该文件时,No package是它返回的一部分:error: No package owns $FILENAME。巧妙的解决方法:我查询__init__.py,因为pacman -Qo对目录有点无知:(

为了在其他发行版上实现此操作,您需要找出pip安装内容的位置(只需使用sudo pip install安装某些内容),如何查询文件所有权(Debian / Ubuntu的方法是dpkg -S),以及“没有软件包拥有该路径”的返回值(Debian / Ubuntu是no path found matching pattern)。Debian / Ubuntu用户请注意:如果您给dpkg -S提供符号链接,则会失败。只需使用realpath先解析它即可。像这样:

find /usr/local/lib/python2.7/dist-packages -maxdepth 2 -name __init__.py | xargs realpath | xargs dpkg -S 2>&1 | grep 'no path found'
find /usr/lib/python2.7/site-packages -maxdepth 2 -name __init__.py | xargs rpm -qf | grep 'not owned by any package'

3
非常感谢您提供的Arch一行命令,这正是我在寻找的。顺便说一下,有趣的事实是:我的Arch安装是意大利本地化的,但grep正确地“匹配”了显示“Nessun pacchetto”(意为“无软件包”)的那些行,即使我搜索的是“No package”。为什么会这样呢? - Nadir Sampaoli
1
@barraponto @NadirSampaoli 在我的情况下,grep 什么也没做。因为 grep 尝试在 stdout 中搜索,但是 dpkg 将错误写入 stderr,所以我必须添加一个重定向 2>&1。为了获得国际化输出,在 xargs dpkg -s 前面加上 LANG= 。而且 sed 也是一个不错的工具 ;),可以只保留路径中的软件包名称。所以最终我得到了这个命令:find /usr/local/lib/python2.7/dist-packages -maxdepth 2 -name __init__.py | xargs realpath | LANG= xargs dpkg -S 2>&1 | grep 'no path found' | sed "s/.*\/\([^\/]*\)\/__init__\.py.*/\1/" - David Boho
1
嗨,我不小心按错了踩的按钮,直到现在才发现,现在我的投票被锁定了。能否有人点赞来抵消我的踩?谢谢。 - Jonathan

10
较新版本的 pip 可以通过 pip list -lpip freeze -l--list)来满足 OP 的需求。
至少在 Debian 上,手册没有明确说明这一点。我仅在 pip list --help 下发现此功能存在的假设下找到了它。 最近的评论表明,无论是文档还是现有答案都不太明显(尽管有些暗示),因此我认为我应该发布这篇文章。我本来更愿意作为评论发表,但我没有足够的声望点数。

1
原来我们已经使用了8年的 pip freeze --localpip list --local 也是可用的...但请注意,OP的问题不是关于虚拟环境(--local支持)的,而是关于区分发行版软件包和 sudo pip install 软件包的问题。 - Capi Etheriel

8

pip.get_installed_distributions()会返回已安装软件包的列表

import pip
from os.path import join

for package in pip.get_installed_distributions():
    print(package.location) # you can exclude packages that's in /usr/XXX
    print(join(package.location, package._get_metadata("top_level.txt"))) # root directory of this package

2
这个已经不再起作用了。请参见 https://github.com/pypa/pip/issues/5243您应该使用:import pkg_resources [print(d.project_name) for d in pkg_resources.working_set] - Almenon

7

在@Paul Woolcock的回答中,还有以下内容需要补充:

pip freeze > requirements.txt

运行该命令将会在当前目录下创建一个需求文件,其中包含了所有已安装的软件包以及它们在当前环境中的版本号。

pip install -r requirements.txt

将会安装在要求文件中指定的软件包。


6
以下内容可能有点慢,但它会给出一个漂亮格式的包列表,这些包是pip所知道的。也就是说,并不是所有这些包都是由pip“安装”的,但是所有这些包都应该能够通过pip进行升级。
$ pip search . | egrep -B1 'INSTALLED|LATEST'

它变慢的原因是因为它列出了整个pypi repo的内容。我提交了一个,建议pip list提供类似的功能,但更加高效。
示例输出:(将搜索限制在子集中而不是“.”表示全部。)
$ pip search selenium | egrep -B1 'INSTALLED|LATEST'

selenium                  - Python bindings for Selenium
  INSTALLED: 2.24.0
  LATEST:    2.25.0
--
robotframework-selenium2library - Web testing library for Robot Framework
  INSTALLED: 1.0.1 (latest)
$

1
为什么不自己提交工单呢? - lajarre
1
显然,下一个版本的pip将具有新的列表命令:http://www.pip-installer.org/en/latest/usage.html#pip-list - MarkHu

4

请注意,如果您的电脑上安装了多个版本的Python,则可能会有几个与每个版本相关联的pip版本。

根据您的关联情况,您可能需要非常谨慎地使用哪个pip命令:

pip3 list 

对我而言有效,因为我正在运行Python3.4。只需使用pip list即可返回错误信息:The program 'pip' is currently not installed. You can install it by typing: sudo apt-get install python-pip


pip适用于Python2.7,pip3适用于Python3.x。 - mjp

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