如何检查代码是否在IPython笔记本中执行?

Chr*_*oph 66 python ipython ipython-notebook

我有一些Python代码示例我想分享,如果在终端Python/IPython或IPython笔记本中执行,应该做一些不同的事情.

如何从我的Python代码中检查它是否在IPython笔记本中运行?

kef*_*ich 40

要检查您是否在笔记本中,这可能很重要,例如在确定使用哪种进度条时,这对我有用:

def in_ipynb():
    try:
        cfg = get_ipython().config 
        if cfg['IPKernelApp']['parent_appname'] == 'ipython-notebook':
            return True
        else:
            return False
    except NameError:
        return False
Run Code Online (Sandbox Code Playgroud)

  • 在我的IPython-Notebook(IPython 3.1版)中,`cfg ['IPKernelApp'] ['parent_appname']`是一个`IPython.config.loader.LazyConfigValue`,它与``iypthon-notebook'的'True`不相比"` (6认同)
  • 或者只是检查get_ipython()是否有效 (6认同)
  • @juanjux get_ipython在ipynb(Jupyter)中返回一个`IPython.kernel.zmq.zmqshell.ZMQInteractiveShell`实例,在终端REPL中返回一个`IPython.terminal.interactiveshell.TerminalInteractiveShell`,以防你需要区分笔记本和终端/控制台(这影响了绘图). (5认同)
  • ^因此你可以用``return str(type(get_ipython()))=="<class'ippykernel.zmqshell.ZMQInteractiveShell'>"替换`try`块的内部. (4认同)

Gus*_*rra 39

以下是我的需求:

get_ipython().__class__.__name__
Run Code Online (Sandbox Code Playgroud)

'TerminalInteractiveShell'在终端IPython 'ZMQInteractiveShell'上返回,在Jupyter(笔记本和qtconsole)上返回,并NameError在常规Python解释器上失败().get_python()默认情况下,启动IPython时,该方法似乎在全局命名空间中可用.

将其包装在一个简单的功能中:

def isnotebook():
    try:
        shell = get_ipython().__class__.__name__
        if shell == 'ZMQInteractiveShell':
            return True   # Jupyter notebook or qtconsole
        elif shell == 'TerminalInteractiveShell':
            return False  # Terminal running IPython
        else:
            return False  # Other type (?)
    except NameError:
        return False      # Probably standard Python interpreter
Run Code Online (Sandbox Code Playgroud)

在MacOS 10.12和Ubuntu 14.04.4 LTS上使用Python 3.5.2,IPython 5.1.0和Jupyter 4.2.1测试了上述内容

  • 如果有人有兴趣检测笔记本是否在Google Colab上运行,你可以查看:`get_ipython().__ class __.__ module__ =="google.colab._shell"` (6认同)
  • 在`jupyter console`上,不幸的是`get_ipython()`也返回了一个`ZMQInteractiveShell`的实例 (4认同)
  • @ChristopherBarber 这不是我所看到的。如果我将此函数粘贴到文件“test.py”中,然后运行“from test import isnotebook;” print(isnotebook())` 在 Jupyter Notebook 中,它打印 `True`。(在笔记本服务器版本 5.2.1 和 6.0.1 上测试。) (4认同)
  • 这仅适用于笔记本中的代码。如果该函数在导入的包中,则它不起作用。 (3认同)
  • 当你输入函数名称“def we_are_in_jupyter()”时,这个答案的代码是由 Github Copilot 自动生成的:) https://imgur.com/9mx9COw 你已经进入了人工智能的大脑 (2认同)

Til*_*ann 21

您可以使用以下代码段[1]检查python是否处于交互模式:

def is_interactive():
    import __main__ as main
    return not hasattr(main, '__file__')
Run Code Online (Sandbox Code Playgroud)

我发现这种方法非常有用,因为我在笔记本中进行了大量的原型设计.出于测试目的,我使用默认参数.否则,我从中读取参数sys.argv.

from sys import argv

if is_interactive():
    params = [<list of default parameters>]
else:
    params = argv[1:]
Run Code Online (Sandbox Code Playgroud)

  • `is_interactive()`不区分笔记本和控制台. (3认同)
  • 这个答案的后半部分很有用,但前半部分(关于“is_interactive”)在我看来基本上与问题无关。它的正确性也值得怀疑;正如 @marscher 指出的,它将使用 `python -c` 运行的任何内容都视为处于“交互”模式,即使这不是真的。我不想自己做,因为这不是我的答案,但我认为通过简单地删除整个答案的前半部分可以改善这一点。 (3认同)
  • 请注意,当从普通 python shell 或运行脚本运行时,“get_ipython”将返回“None”,因此此代码需要防止这种情况。 (2认同)

dee*_*nes 13

最近我在Jupyter笔记本中遇到了一个需要解决方法的错误,我希望这样做而不会丢失其他shell中的功能.我意识到keflavich的解决方案在这种情况下不起作用,因为get_ipython()它只能直接从笔记本电脑上获得,而不能从导入的模块中获得.所以我找到了一种从我的模块中检测它是否从Jupyter笔记本导入和使用的方法:

import sys

def in_notebook():
    """
    Returns ``True`` if the module is running in IPython kernel,
    ``False`` if in IPython shell or other Python shell.
    """
    return 'ipykernel' in sys.modules

# later I found out this:

def ipython_info():
    ip = False
    if 'ipykernel' in sys.modules:
        ip = 'notebook'
    elif 'IPython' in sys.modules:
        ip = 'terminal'
    return ip
Run Code Online (Sandbox Code Playgroud)

如果足够强大,则表示赞赏.

类似的方式可以获得有关客户端和IPython版本的一些信息:

import sys

if 'ipykernel' in sys.modules:
    ip = sys.modules['ipykernel']
    ip_version = ip.version_info
    ip_client = ip.write_connection_file.__module__.split('.')[0]

# and this might be useful too:

ip_version = IPython.utils.sysinfo.get_sys_info()['ipython_version']
Run Code Online (Sandbox Code Playgroud)

  • IMO,这是迄今为止最好的答案。简短而甜蜜。 (3认同)

Rob*_*wak 13

针对 python 3.7.3 进行了测试

CPython 实现的名称可__builtins__作为其全局变量的一部分,顺便说一句。可以通过函数 globals() 检索。
如果脚本在 Ipython 环境中运行,那么__IPYTHON__应该是__builtins__.
因此,如果在 Ipython 下运行,下面的代码将返回True,否则它给出False

hasattr(__builtins__,'__IPYTHON__')
Run Code Online (Sandbox Code Playgroud)

  • 被否决——在 IPython 会话中也是如此 (5认同)
  • 您可能应该“导入内置函数”并检查“hasattr(builtins, "__IPYTHON__")”,因为[`__builtins__`是一个实现细节](https://docs.python.org/3/library/builtins.html)这可能会改变。 (3认同)
  • @jtlz2您可能错过了字符串周围的引号。 (2认同)

Mat*_*att 8

问题是你想要以不同的方式执行什么.

我们在IPython中尽力而为,防止内核知道连接的是哪种前端,实际上你甚至可以同时将内核连接到许多不同的前端.即使您可以看一下stderr/out您是否知道ZMQ内核中的类型,但它并不能保证您在另一方面拥有的内容.你甚至可以没有前端.

您应该以独立于前端的方式编写代码,但是如果要显示不同的内容,可以使用富显示系统(链接到IPython的4.x版本)根据前端显示不同的内容,但是前端会选择,而不是图书馆.

  • 我有一个例子:进度条.Jupyter笔记本终端仿真器不支持扩展终端控制字符,如`\ x1b [A`(向上移动),因此无法打印[嵌套条](https://github.com/tqdm/tqdm#nested-progress -bars).没有问题[ipywidgets](https://github.com/ipython/ipywidgets),我们可以使用原生的Jupyter小部件来显示进度条.但是我们有两种不同的显示进度条的方法,应用程序可能想知道什么是显示环境以适应和打印兼容的条. (19认同)
  • 虽然这是一个完全有效的意见,但此答案并未解决实际问题。无论您多么希望它,否则总会有可能重要的行为差异。 (9认同)
  • 这并没有回答所提出的问题。标题是“如何检查代码是否在 IPython 笔记本中执行?” 请更改正确答案或问题标题。 (6认同)
  • 例如,我想将 IPython 配置设置为在充当笔记本时始终运行 `%matplotlib inline`,而不是在终端中,因为不需要。 (3认同)
  • 初衷是好的,但做法却不同。让代码依赖于环境是有充分理由的。我的应用程序是启动文件“startup.ipy”。当在 IPython 终端中时,为了方便起见,我喜欢预先导入一些包。在笔记本中,这被认为是不好的风格,并且没有必要,因为我可以将导入放在第一个单元格中,而不必一次又一次地键入它们。 (3认同)
  • 上面的IPython Rich Display System链接已损坏.以下是当前文档的链接:http://ipython.org/ipython-doc/dev/config/integrating.html,这里有一些很好的例子的链接:http://nbviewer.ipython.org/github/ IPython的/ IPython的/斑点/主/示例/笔记本/显示%20System.ipynb (2认同)
  • 我的[绘图模块](https://github.com/goulu/Goulib/blob/master/Goulib/drawing.py)中有这样的问题.我需要在那里为travis-ci导入调用matplotlib.use("Agg")以允许保存图纸(参见http://stackoverflow.com/questions/4706451/how-to-save-a-figure-remotely-with- pylab/4706614#4706614)但这会产生警告[在笔记本中](http://nbviewer.ipython.org/github/Goulu/Goulib/blob/master/notebook.ipynb)UserWarning:这个调用matplotlib.use( )因为已经选择了后端,所以没有效果; 怎么解决这个? (2认同)
  • 许多用户实际上可能只需要知道他们是否在内核中,不一定在笔记本中,这可以通过 https://github.com/ipython/ipython/issues/11694 完成 (2认同)
  • 在我的示例中,我的脚本中有一行“display(HTML(...))”。当从笔记本运行时它可以工作。当作为普通的Python脚本运行时,它只打印`&lt;IPython.core.display.HTML object&gt;`,这是无用的,所以我需要手动打开浏览器来显示HTML代码,或者将HTML转换为我可以打印的东西在终端中。 (2认同)