使用多个 Python 和 IPython 路径运行 Jupiter

我想使用 Jupiter 笔记本电脑,但是在进行基本的导入(比如导入 matplotlib)时遇到了困难。我认为这是因为我有几个用户管理的 python 安装。例如:

> which -a python
/usr/bin/python
/usr/local/bin/python


> which -a ipython
/Library/Frameworks/Python.framework/Versions/3.5/bin/ipython
/usr/local/bin/ipython


> which -a jupyter
/Library/Frameworks/Python.framework/Versions/3.5/bin/jupyter
/usr/local/bin/jupyter

我以前有蟒蛇,但是从 ~/anaconda 目录中删除了它。现在,当我开始一个木星笔记本,我得到一个内核错误:

File "/Library/Frameworks/Python.framework/Versions/3.5/lib/pytho‌n3.5/subprocess.py",
line 947, in init restore_signals, start_new_session)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/pytho‌n3.5/subprocess.py",
line 1551, in _execute_child raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2]
No such file or directory: '/Users/npr1/anaconda/envs/py27/bin/python'

我该怎么办!

76130 次浏览

解决这个问题相当简单,但需要理解三个不同的概念:

  1. Unix/Linux/OSX 如何使用 $PATH查找可执行文件(Windows 中的 %PATH%)
  2. Python 如何安装和查找包
  3. Jupiter 是如何知道使用 Python 的

为了完整起见,我将尝试对每个问题做一个快速的 ELI5,这样您就会知道如何以最佳方式解决这个问题。

1. Unix/Linux/OSX $PATH

当您在提示符下键入任何命令(比如 python)时,系统有一个定义良好的位置序列来查找可执行文件。这个序列在一个名为 PATH的系统变量中定义,用户可以指定该变量。要查看您的 PATH,您可以键入 echo $PATH

结果是计算机上的目录列表,将在 按顺序中搜索所需的可执行文件。根据您上面的输出,我假设它包含以下内容:

$ echo $PATH
/usr/bin/:/Library/Frameworks/Python.framework/Versions/3.5/bin/:/usr/local/bin/

在窗口 echo %path%

可能还有其他路径。这意味着当您键入 python时,系统将转到 /usr/bin/python。当您键入 ipython时,在本例中,系统将转到 /Library/Frameworks/Python.framework/Versions/3.5/bin/ipython,因为在 /usr/bin/中没有 ipython

了解您正在使用的可执行文件总是很重要的,特别是当您的系统上安装了如此多的同一个程序时。更改路径并不太复杂; 参见例如 如何在 Linux 上永久设置 $PATH?

视窗 -如何在 Windows10中设置环境变量

2. Python 如何找到软件包

当您运行 Python 并执行类似 import matplotlib的操作时,Python 必须进行类似的游戏才能找到您想要的包。与 unix 中的 $PATH类似,Python 中的 sys.path指定了以下内容:

$ python
>>> import sys
>>> sys.path
['',
'/Users/jakevdp/anaconda/lib/python3.5',
'/Users/jakevdp/anaconda/lib/python3.5/site-packages',
...]

一些重要的事情: 默认情况下,abc0中的第一个条目是工作目录。另外,除非你修改它(你不应该这样做,除非你确切知道你在做什么) ,你通常会在路径中找到一个叫做 site-packages的东西: 这是 Python 在你使用 python setup.py install,或者 pip,或者 conda或者类似的方法安装软件包时放置软件包的默认位置。

需要注意的重要事情是 每个 python 安装都有自己的站点包,其中安装了包 那个特定的 Python 版本。换句话说,如果您为 /usr/bin/python安装了某些东西,那么 ~/anaconda/bin/python 不能用那个包裹,因为它是安装在另一个 Python 上的!这就是为什么在我们的 twitter 交流中,我建议您专注于一个 Python 安装,并修复您的 $PATH,以便您只使用您想要使用的那个。

这里还有另外一个组件: 一些 Python 包附带了独立的脚本,你可以从命令行运行它们(例如 pipipythonjupyterpep8等等)。默认情况下,这些可执行文件会被放在 相同的目录路径中,就像 Python 用来安装它们一样,并且被设计成可以工作在 只有在安装了 Python 的情况下中。

这意味着,当您的系统已经设置好时,当您运行 python时,您将得到 /usr/bin/python,但是当您运行 ipython时,您将得到 /Library/Frameworks/Python.framework/Versions/3.5/bin/ipython,它与在 /Library/Frameworks/Python.framework/Versions/3.5/bin/python处的 Python 版本相关联!此外,这意味着运行 python时可以导入的包与运行 ipython或 Jupiter 笔记本时可以导入的包是完全独立的: 您正在使用两个完全独立的 Python 安装。

那怎么解决这个问题呢?那么,首先确保您的 $PATH变量正在做您希望它做的事情。您可能有一个名为 ~/.bash_profile~/.bashrc的启动脚本来设置这个 $PATH变量。在 Windows 上,可以修改用户特定的环境变量。如果您希望系统以不同的顺序搜索内容,可以手动修改它。当您第一次安装 anaconda/miniconda 时,会有一个自动执行的选项(将 Python 添加到 PATH 中) : 对此说 yes,然后 python将始终指向 ~/anaconda/python,这可能就是您想要的。

3. Jupiter 是如何知道使用 Python 的

我们还没完全脱离险境。您在 Jupiter 笔记本中提到,您得到了一个内核错误: 这表明 Jupiter 正在寻找一个不存在的 Python 版本。

木星是建立在能够使用广泛的“内核”,或执行引擎的代码。可以是 Python2、 Python3、 R、 Julia、 Ruby... ... 有几十种可用的内核。但是为了实现这一点,Jupiter 需要知道 哪里来寻找相关的可执行文件: 也就是说,它需要知道 python所在的路径。

这些路径在木星的 kernelspec中指定,用户可以根据自己的需要调整它们。例如,下面是我系统上的内核列表:

$ jupyter kernelspec list
Available kernels:
python2.7        /Users/jakevdp/.ipython/kernels/python2.7
python3.3        /Users/jakevdp/.ipython/kernels/python3.3
python3.4        /Users/jakevdp/.ipython/kernels/python3.4
python3.5        /Users/jakevdp/.ipython/kernels/python3.5
python2          /Users/jakevdp/Library/Jupyter/kernels/python2
python3          /Users/jakevdp/Library/Jupyter/kernels/python3

每个目录都包含一些元数据,这些元数据指定内核名称、可执行文件的路径和其他相关信息。
您可以手动调整内核,编辑上面列出的目录中的元数据。

安装内核的命令可以根据内核的不同而改变。IPython 依赖于包含安装 python 内核命令的 Ipykernel 软件包: 例如

$  python -m ipykernel install

它将创建一个与用于运行此命令的 Python 可执行文件相关联的内核规范。然后,您可以在 Jupiter 笔记本中选择这个内核,用 Python 运行代码。

您可以使用 help 命令查看 ipykernel 提供的其他选项:

$ python -m ipykernel install --help
usage: ipython-kernel-install [-h] [--user] [--name NAME]
[--display-name DISPLAY_NAME] [--prefix PREFIX]
[--sys-prefix]


Install the IPython kernel spec.


optional arguments:
-h, --help            show this help message and exit
--user                Install for the current user instead of system-wide
--name NAME           Specify a name for the kernelspec. This is needed to
have multiple IPython kernels at the same time.
--display-name DISPLAY_NAME
Specify the display name for the kernelspec. This is
helpful when you have multiple IPython kernels.
--prefix PREFIX       Specify an install prefix for the kernelspec. This is
needed to install into a non-default location, such as
a conda/virtual-env.
--sys-prefix          Install to Python's sys.prefix. Shorthand for
--prefix='/Users/bussonniermatthias/anaconda'. For use
in conda/virtual-envs.

注意: 最新版本的 水蟒附带了一个笔记本扩展,如果 ipykernel软件包安装在里面,它会自动检测各种 conda 环境。

总结: 解决你的问题

因此,在这种背景下,你的问题很容易解决:

  1. PATH设置为首先是所需的 Python 版本。例如,您可以运行 export PATH="/path/to/python/bin:$PATH"来指定(一次)您希望使用哪种 Python。为了永久地做到这一点,将这一行添加到 .bash_profile/.bashrc(注意,当您安装蟒蛇时,它可以自动为您做到这一点)。我建议使用蟒蛇或 miniconda 附带的 Python: 这将允许您使用 conda install所需的所有工具。

  2. 确保要使用的包是为 那个 python 安装的。如果您正在使用 conda,您可以输入,例如 conda install jupyter matplotlib scikit-learn来为 anaconda/bin/python安装这些包。

  3. 确保 Jupiter 内核指向希望使用的 Python 版本。当你的 conda install jupyter它应该为 anaconda/bin/python自动设置这个。否则,您可以使用 jupyter kernelspec命令或 python -m ipykernel install命令来调整现有的内核或安装新的内核。

  4. 要将模块安装到 Anaconda 不管理的其他 Python Jupiter 内核中,需要将路径复制到内核的 Python 可执行文件并运行 /path/to/python -m pip install <package>

希望这是明确的... 祝你好运!

@ jakevdp 解释得很好。

当我更新 ubuntu 时,我也遇到了同样的问题,我通过更改内核配置文件(kernel.json)解决了这个问题。 列出内核文件位置。 使用

jupyter kernelspec list

它会回来的

Available kernels:
python3    /home/user1/.local/share/jupyter/kernels/python3
python2    /usr/local/share/jupyter/kernels/python2

我正在使用 python3,所以我在

/home/user1/.local/share/jupyter/kernels/python3

通过以下步骤

nano /home/user1/.local/share/jupyter/kernels/python3/kernel.json

在里面 argv 我更改了第一个参数(即 python3目录路径)的表单

"/usr/bin/python3.5"

"/usr/bin/python3"

并保存它与 ctr+x 重新启动了木星笔记本。

还发现不要将虚拟环境放在 git repo 中,因为它对于读取 python 包来说是不可读的。似乎不同的权限使用时,读和写(写-安装一个包-使用 pip) ,如何无法读。因此,对我来说,Python 库是从系统安装而不是虚拟环境中读取的。

上面@jakevdp 的回答和他的博客 https://jakevdp.github.io/blog/2017/12/05/installing-python-packages-from-jupyter/给出了一个相当好的想法,关于出了什么问题,但是仅仅从 shell 更新路径对我来说不起作用,有两种方法对我来说起作用

要么更新路径笔记本上使用魔术命令,运行下面的单元格

originalPath = %env PATH
%env PATH = [local anaconda path]/kernels/[custom_kernel]/bin/:$originalPath

或者您甚至可以更新 kernel.json 并在 env 中设置路径

{
"argv": [
"[custom kernel path]/bin/python",
"-m",
"ipykernel_launcher",
"-f",
"{connection_file}"
],
"env": {
"PATH": "[custom kernel path]/bin/:[rest of the paths]"
},


"display_name": "custom_kerbel",


"language": "python"
}

如果您只是想将一个包安装到当前环境中以便能够导入它,那么您可以使用 %pip%conda魔术。

正如您所提到的,您可能应该使用 conda来安装:

# Install a conda package in the current Jupyter kernel
%conda install <dependency_name>

或者,如果你需要使用 pip:

# Install a pip package in the current Jupyter kernel
%pip install <python_package_name>