如何检测和移除通过pip安装的Python包?

我不小心使用pip而不是apt-get将Python包安装到了我的系统上。我有两种方式做错了:
1. 在使用较旧版本的virtualenv时,我忘记在创建虚拟环境时添加--no-site-packages选项 - 之后当我调用pip install时,Python包被安装到了系统而不是虚拟环境中。 2. 在正确设置的虚拟环境中,我输入了sudo pip install somepackage - sudo命令将其安装到了系统而不是虚拟环境中。
我注意到这个问题是因为我在虚拟环境外面输入了pip freeze,并发现了一些不应该存在的Python包。所以现在我的问题是:
1. 如何识别所有错误安装在系统上的Python包(即出现在pip freeze列表中但没有使用apt-get安装的Python包)? 2. 如何删除它们?
7个回答

Ubuntu Oneiric(我预计更新的版本也是如此)将pip软件包安装到/usr/local/lib/python2.7/dist-packages,并将apt软件包安装到/usr/lib/python2.7/dist-packages。因此,只需检查前一个目录,然后sudo pip uninstall找到的每个软件包。

14我变得野蛮,并发出了 sudo rm -r /usr/local/lib/python2.7 命令。到目前为止一切顺利。 - Apteryx
@Apteryx,我也对/usr/local/lib/python3.5做了同样的操作,但过了一会儿,update-notifier-common软件包的升级因缺少Python 3的six软件包而失败。最终我使用sudo -H pip3 install six安装了six软件包。 - Alexey
7@ Apteryx该死的,你这个家伙!我也做了同样的事,现在我的整个系统都搞砸了!因为几乎所有Ubuntu系统都依赖Python! - yukashima huksay
1我注意到现在/usr/local/bin/目录下有一堆损坏的可执行文件(一段时间前我刚刚删除了/usr/local/lib/python3.5并转而使用conda)。 - Alexey

Pip目前忽略了试图卸载操作系统拥有的内容的卸载命令。与缺少软件包时不同,它不会报错。因此,现在您可以按照以下步骤进行卸载:
pip freeze > dump.txt

编辑转储文件,删除任何“可编辑安装”行中的-e,以及等号后面的所有内容(在vim中为%s;==.*;;g),将换行符替换为空格(在vim中为%s;\n; ;g)。然后,您可以使用以下命令卸载所有未拥有的软件包:
cat dump.txt | xargs sudo pip uninstall -y

我不得不做这个过程两次,因为一些软件包也安装在~/.local/lib中。
一行代码就能完成这个任务。
pip freeze | grep -vP '^(?:#|-e\s)' | sed 's;==.*;;g' | xargs -r sudo pip uninstall -y

1这对我来说应该是被接受的答案。 - Nam G VU
5如果有人想要一个无篇幅的一行代码,可以尝试执行以下命令:sudo pip uninstall -y $(pip freeze | sed 's;==.*;;g' | tr '\n' ' ') - Benoit Duffez
6小心!这取决于您的操作系统是否提供了特殊版本的 “pip”。在 archlinux 上,“pip” 会快乐地卸载系统软件包。另一方面,在 debian jessie上,"pip" 抱怨并出错:不卸载属于操作系统的 /usr/lib/python3/dist-packages 中的 virtualenv - Thomas G.
1你需要sudo吗?- 这绝对应该是被接受的答案。 - Jonathan
有没有猜到如果我得到“找到现有安装:Routes 2.4.1 不在 /usr/lib/python3/dist-packages 卸载 routes,因为它在 /usr 之外的环境 无法卸载 'Routes'。找不到要卸载的文件。 ”(对于每个已安装的软件包)是什么意思?(在 Ubuntu focal 上) - Jonathan Hartley
这个解决方案非常棒,但在Ubuntu上运行时会遇到中止distutils已安装的项目的问题。 - Sigmatics

据我所知,sudo pip install会安装在/usr/local/lib/pythonVERSION/dist-packages目录下。要卸载系统范围内的软件包,您需要运行sudo pip uninstall命令。似乎pip freeze会查找软件包元数据,并列出所有已安装的内容,即来自pip和apt-get的内容,而不仅限于虚拟环境。在虚拟环境中,有一个-l选项可以列出仅适用于该虚拟环境的软件包,但它似乎也是默认情况下的。我认为您也可以直接删除/usr/local/lib/pythonVERSION/dist-packages目录下的相关软件包,但这可能不是非常方便的方法。

要通过pip删除一个安装的软件包,只需在键盘上按下Ctrl+Alt+T打开终端。当终端打开后,运行以下命令即可。
pip uninstall < package-name >

搜索包裹
pip search <package you want to search for>

要确定哪些Python包是通过pip安装的,可以使用freeze命令,它会给出已安装包及其版本的列表。我建议删除所有实例,并使用sudo apt-get命令重新安装。
sudo apt-get install python3

1如何确定是通过pip还是apt-get安装的Python包?如果我一开始使用了sudo pip install,那么我还能使用pip uninstall吗? - lofidevops
@d3vid pip freeze只会显示它安装的包(据我所见)。 - Oli
1@oli pip freeze在精确模式下至少也会列出通过apt安装的软件包,正如其他答案中所描述的。 - nealmcb

我需要安全地清理Python包占用的磁盘空间。虽然这是对包的完全清理,但我还需要移动Python版本,以便不再需要旧的包。我使用以下方法获取所有的包名,跳过前两行并提取第一列,并且在没有用户交互的情况下进行卸载:
pip list | awk 'NR>2 {print $1}' | xargs -I {} pip uninstall -y {}

我使用以下方法从我的虚拟环境中卸载了所有的pip包:
pip list | tail -n+3 | grep -ve '^#\|^wheel\|^pip\|^setuptools ' | cut -d' ' -f1 | xargs pip uninstall -y

我仍然保留着wheel、pip和setuptools。
此外,在我的情况下,我更喜欢使用pip list而不是pip freeze,因为pip list只列出了以-e安装的包的名称。

这与Homebrew有关。在我安装Homebrew并使用它进行一些操作之前,我的Mac Air上的pyodbc没有任何问题。我在github上找到了这个讨论串,其中提供了一个对我有效的解决方案。
"如果你已经安装了Homebrew,只需要安装ODBC头文件即可:
$ brew install unixodbc

并再次运行“pip install pyodbc”。

这个方法对我来说百分之百解决了问题,并且只花了一会儿。试一试吧。


也许你应该在Ask Different上发布这个问题?https://apple.stackexchange.com - lofidevops