运行具有多个Python和IPython路径的Jupyter

77

我想使用Jupyter笔记本,但是在进行基本导入(如import 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,但是现在已将其从~/anaconda目录中删除。现在,当我启动Jupyter Notebook时,会出现Kernel Error:

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' 

我该怎么办?!

5个回答

225

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

  1. Unix/Linux/OSX如何使用$PATH来查找可执行文件(在Windows中为%PATH%
  2. Python如何安装和查找软件包
  3. Jupyter如何知道要使用哪个Python环境

为了全面起见,我将尝试简单地解释一下每个概念,以便您能够找到最适合您的解决方法。

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/

在Windows中,使用echo %path%命令可以显示环境变量路径列表,其中可能包含其他路径。这意味着,当您键入python命令时,系统将进入/usr/bin/python路径。例如,当您键入ipython命令时,系统将进入/Library/Frameworks/Python.framework/Versions/3.5/bin/ipython路径,因为/usr/bin/中没有ipython

特别是在系统上安装了多个相同程序的情况下,了解您正在使用的可执行文件非常重要。更改路径并不太复杂;例如,请参见如何在Linux上永久设置$PATH?.

Windows - 如何在Windows 10中设置环境变量

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',
 ...]

重要的一些事情:默认情况下,sys.path中的第一个条目是当前目录。此外,除非您修改它(除非您确切知道自己在做什么),否则您通常会在路径中找到名为site-packages的东西:这是Python在使用python setup.py installpipconda或类似手段安装包时的默认位置。

需要注意的重要事项是每个Python安装都有自己的site-packages,其中安装了针对该特定Python版本的软件包。换句话说,如果您为例如/usr/bin/python安装了某些内容,则~/anaconda/bin/python无法使用该软件包,因为它是安装在不同版本的Python上!这就是为什么在我们的推特交流中,我建议您集中精力解决一个Python安装问题,并修复$PATH,以便您只使用想要使用的那个Python。

还有另一个组成部分:某些Python软件包附带独立脚本,您可以从命令行运行(例如pipipythonjupyterpep8等)。默认情况下,这些可执行文件将被放置在安装它们的Python相同的目录路径中,并且设计为仅与该Python安装一起使用。

这意味着,根据您的系统设置,当您运行python时,您会得到/usr/bin/python,但当您运行ipython时,您会得到与位于/Library/Frameworks/Python.framework/Versions/3.5/bin/python的Python版本相关联的/Library/Frameworks/Python.framework/Versions/3.5/bin/ipython!此外,这意味着在运行python时可以导入的软件包完全与在运行ipython或Jupyter笔记本时可以导入的软件包分开:您正在使用两个完全独立的Python安装。

那么如何解决这个问题?首先确保您的$PATH变量正在执行您想要的操作。您可能有一个名为~/.bash_profile~/.bashrc等启动脚本,用于设置这个$PATH变量。在Windows上,您可以修改用户特定环境变量。如果您希望系统按不同的顺序搜索内容,则可以手动修改它。在首次安装anaconda/miniconda时,将有一个选项自动完成这个步骤(将Python添加到PATH):选择是,然后python将始终指向~/anaconda/python,这可能是您想要的。

3. Jupyter如何知道要使用哪个Python

我们还没有完全脱离困境。你提到在Jupyter Notebook中,你得到了一个内核错误:这表明Jupyter正在寻找不存在的Python版本。

Jupyter被设置成能够使用各种“内核”,或者说是代码执行引擎。这些可以是Python 2、Python 3、R、Julia、Ruby 等等……有数十种可能的内核可供使用。但为了实现这一点,Jupyter需要知道它应该去哪里查找相关的可执行文件:也就是说,它需要知道python所在的路径。

这些路径在jupyter的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 依赖 ipykernel 包,该包包含一个安装 Python 内核的命令:例如

$  python -m ipykernel install

运行此命令使用的Python可执行文件将创建与之关联的内核规范。然后,您可以在Jupyter笔记本中选择此内核以使用该Python运行代码。

您可以使用帮助命令查看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.

注意:最近版本的anaconda附带了一个扩展程序,可自动检测您各种conda环境,如果其中安装了ipykernel包。

总结:修复您的问题

有了这个背景,您的问题就很容易解决:

  1. 设置您的PATH,使期望的Python版本处于首位。例如,您可以运行export PATH="/path/to/python/bin:$PATH"来指定(一次性)您想使用的Python。要永久进行此操作,请将该行添加到.bash_profile/.bashrc中(请注意,安装anaconda时,它可以自动为您执行此操作)。我建议使用与anaconda或miniconda捆绑的Python:这将使您能够conda install所有需要的工具。

  2. 确保您想要使用的软件包已安装在那个 Python上。如果您使用conda,可以键入例如conda install jupyter matplotlib scikit-learn来为anaconda/bin/python安装这些软件包。

  3. 确保您的Jupyter kernels指向您想要的Python版本。当您安装jupyter时,它应自动为anaconda/bin/python进行设置���否则,您可以使用jupyter kernelspec命令或python -m ipykernel install命令来调整现有内核或安装新内核。

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


1
对我来说,这个命令有效:python -m ipykernel install --user - IY4

9

@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"

to

"/usr/bin/python3"

我使用 Ctrl + X 进行保存,并重新启动了 Jupyter Notebook。


如何将Python版本添加到可用内核中? - Nathan B

1
也发现不要把你的虚拟环境放在git仓库里,因为它会变得无法读取python包。看起来在读写时使用了不同的权限(写入-安装包-使用pip),导致无法读取。因此,对我来说,Python库是从系统安装中读取的,而不是虚拟环境中读取的。

0

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

由于您提到了Anaconda,因此您应该使用 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>

0

@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"
}

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