pip:卸载 disutils 安装包

pip: uninstalling a disutils installed package

我正在尝试使用命令 pip install -U psutil 安装 psutil,这给了我错误:

Cannot uninstall 'psutil'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

这似乎是 pipversions > 10 中的一个 known 问题,我理解那部分(我目前有 pip 18)。但是我刚刚发现我可以通过直接执行 pip install psutil 而不使用 Upgrade 标志来解决它。我想知道这背后是否有原因。我的初步感觉是,在第一种情况下,pip 尝试升级,它首先尝试删除包,但它不能,但在后一种情况下,它尝试直接安装,因此不会出现错误.我的问题是它是否仍然不必先删除包并安装(当不使用升级标志时),或者为什么 pip 给出带有升级标志的错误但没有它没有错误。

编辑:所以,我尝试 运行 pip install -v psutil 按照 hoefling 的建议,我得到了一大堆文本,而不是说已经满足要求,这意味着首先没有安装 psutil。我试图弄清楚这一点,这是我目前所了解的:我在 运行 中 python virtualenv 并通过 pip -U -r requirements.txt 安装它,其中 requirements.txt 包含一堆包,包括 psutil。当我删除 -U 标志时,它会跳过安装 psutil,并跳转到其他包。这就提出了另一个问题,这是否是 pip 在没有 -U 标志时的行为方式。有趣的是,当它第一次安装带有 -U 标志的软件包时,它会在主 python 安装内部而不是虚拟环境中查找,并且当 -U 标志被删除时它不会那样做并完全跳过。

在某些设置中,您在 setuptools 的正常安装位置以外的地方安装了一堆软件包,并且位于 sys.path.[=35 的正常安装位置之后=]

这些设置中最常见的可能是 Apple 预装的 Python 2.7,因此我将以它为例。即使这不是您的设置,也希望它仍然具有指导意义。

Apple 包含一个 Extras 目录(位于 /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python),其中包含 Apple 自己的工具所需的一堆第三方软件包,或者 Apple 认为您可能需要的软件包(回到 Apple 关心的时候关于提供任何平台的最佳 Python 体验)。

例如,在 macOS 10.13 上,该目录将包含 NumPy 1.8.0。

这些包都安装为 distribute-style eggs。

(一些 linux 发行版做,或者至少曾经做过类似的事情,Python 包构建为 RPM/DEB/etc。包,进入 distutils 目录,不像你通过 pip 或手动安装的东西,它进入 setuptools 目录。细节有点不同,但效果和解决方法最终是相同的。)

如果安装 pip,然后尝试 pip install -U numpypip uninstall numpypip 将看到 distribute 样式 numpy-1.8.0rc1-py2.7.egg-info文件并拒绝触摸它,以免破坏一切。

但是,如果你只是 pip install numpy,它只会在 setuptools/Library/Python/2.7/site-packages 使用的标准站点包安装位置查找,在那里什么也看不到,并愉快地安装一个为您准备的现代版 NumPy。

而且,因为 /Library/Python/2.7/site-packagessys,path 之前出现在 /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python 之前,新的 NumPy 将隐藏旧的 NumPy,一切都会按预期工作。

这可能会有一些问题。最值得注意的是,如果您尝试安装 Extras 本身未包含的东西,但它具有 包含在 Extras 中的依赖项,它可能会因神秘且难以调试而失败错误。例如,在 macOS 10.12 上,pip install pandas 会向您抛出一堆关于无法升级 dateutil 的错误,您甚至都不知道自己正在尝试这样做。您唯一可以做的就是查看 pandas 的依赖项,查看 Extras 中预安装了哪些依赖项,然后手动 pip install 隐藏所有这些依赖项的版本。

但是,在大多数情况下,它是有效的。