在相当新的 Ubuntu 16.04 上,我正在使用 pip 安装 ipython,作为用户安装。Pip 本身是从python-pip
Ubuntu 软件包 (8.1.1) 安装的,一些依赖项(如 pygments 或 setuptools (20.7.0))也是如此。
我的问题是:使用 pip 进行用户安装时,无法检测到 apt-get 安装的软件包,这正常吗?这是一个已知的错误吗?
这是我运行的命令(作为用户,而不是作为 root):
$ pip install ipython
→ 我从 PyPI 下载了许多软件包,包括 setuptool (27.3.0) 和 Pygments (2.1.3)。我认为这不是版本问题,因为 ipythonsetuptools>=18.5
只需要。顺便说一句,我还收到一条投诉,说 pip 应该更新到最新版本 (8.1.2)。
更有趣的是,当我再次运行相同的命令时,我得到了相同的安装过程(唯一的区别:wheels 被缓存了)。相反,我期望 pip 告诉我 ipython 已经安装。
请注意,毫无疑问,ipython(版本 5.1.0)确实安装在我的~/.local
目录中,并且运行良好(我唯一需要做的调整是添加~/.local/bin
到变量PATH
中,~/.bashrc
如专门问题)。
我觉得 pip 检测 apt-get 安装包的方式有问题,但我搞不清楚是什么问题。我是不是忽略了某些显而易见的东西?
如果它可以帮助诊断,这是 Python 模块路径(modelica 是用户名):
python -c "import sys; print sys.path"
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/modelica/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/omniORB/COS', '/usr/lib/python2.7/dist-packages/gtk-2.0']
答案1
使用 pip 进行用户安装时,apt-get 安装的软件包无法被检测到,这正常吗?这是一个已知的错误吗?
我刚刚深入研究了 pip 的代码,发现 pip 的list
命令会过滤由以下程序提供的软件包列表:复制代码,它又从 中获取条目sys.path
。结果是pip --list
还将列出 APT 安装的系统包。但这并不意味着 pip 应该管理这些包。
Pip 和 APT 的工作方式不同,首先从它们的安装位置开始:pip 全局安装到/usr/lib/pythonX.Y/site-packages
或/usr/local/lib/pythonX.Y/dist-packages
(取决于版本)并本地安装到~/.local/lib/pythonX.Y/site-packages
,而基于 APT 的工具全局安装到/usr/lib/pythonX.Y/dist-packages
。
这个奇怪的现象与Debian 开发人员的设计决策以避免它们提供的软件包与通过其他方式获得的软件包发生冲突(这个 Stack Overflow 上的答案为我指明了正确的方向)。
~/.local/lib/pythonX.Y/site-packages
因此,即使包已经安装在 中,/usr/lib/pythonX.Y/dist-packages
pip仍允许您安装包,这并不是一个错误。
让我们看看你的 ipython 示例。我之前也用 APT 安装过它:
DEB 软件包
$ dpkg --get-selections | grep ipython ipython 安装 $ dpkg -s ipython | grep 版本 版本:2.4.1-1 $ dpkg-query -L ipython (...) /usr/lib/python2.7/dist-packages (...) 在/usr/bin/ipython (...)
Pip 包
$ pip 显示-f ipython (...) 名称:ipython 版本:5.3.0 (...) 安装程序:pip (..) 位置:/usr/local/lib/python2.7/dist-packages 文件: ../../../bin/ipython
注:../../../bin/ipython
最终为/usr/local/bin/ipython
。
该命令whereis
给出了两个 IPython 实例:
$ whereis -b ipython
ipython: /usr/bin/ipython /usr/local/bin/ipython
~/.local
如果我愿意的话,我仍然可以获得第三个 IPython !
更有趣的是,当我再次运行相同的命令时,我得到了相同的安装过程(唯一的区别:wheels 被缓存了)。相反,我期望 pip 告诉我 ipython 已经安装。
这确实很奇怪。以下是我目前观察到的情况:当某个包已由 pip 在本地安装时,它似乎每次都能安装(它总是输出“已成功安装 {package}”),但它实际上似乎只是改变了包的 dist-info。例如,我尝试在本地安装 lxml(使用pip install lxml
或pip install --user lxml
)几次:
将第一次 lxml 安装的时间戳与最后一次 lxml“安装”后的时间戳进行比较:
1.
myusr@myhost:~$ ls -al .local/lib/python2.7/site-packages | grep lxml drwxrwxr-x 5 myusr mygroup 4096 2月 20 15:01 lxml drwxrwxr-x 2 myusr mygroup 4096 2 月 20 日 15:01 lxml-3.7.3.dist-info
2.
myusr@myhost:~$ ls -al .local/lib/python2.7/site-packages | grep lxml drwxrwxr-x 5 myusr mygroup 4096 2月 20 15:01 lxml drwxrwxr-x 2 myusr mygroup 4096 2 月 20 日 15:03 lxml-3.7.3.dist-info
但是,当尝试全局安装包时,pip做显示消息:
Requirement already satisfied (use --upgrade to upgrade): ipython in /usr/local/lib/python2.7/dist-packages
答案2
尝试
python3 -m pip install ipython
对于我来说工作