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

152 投票
18 回答
69489 浏览
提问于 2025-04-17 19:06

我有一些Python代码示例想分享,这段代码在终端的Python或IPython中执行时应该做不同的事情,而在IPython笔记本中执行时又是另一种情况。

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

18 个回答

46

你可以用下面的代码来检查 Python 是否处于交互模式 [1]

def is_interactive():
    import __main__ as main
    return not hasattr(main, '__file__')

我发现这个方法非常有用,因为我在笔记本上做很多原型测试。为了测试,我使用默认参数。否则,我会从 sys.argv 中读取参数。

from sys import argv

if is_interactive():
    params = [<list of default parameters>]
else:
    params = argv[1:]

根据 autonotebook 的实现,你可以用下面的代码来判断你是否在笔记本中。

def in_notebook():
    try:
        from IPython import get_ipython
        if 'IPKernelApp' not in get_ipython().config:  # pragma: no cover
            return False
    except ImportError:
        return False
    except AttributeError:
        return False
    return True
137

以下内容满足了我的需求:

get_ipython().__class__.__name__

在终端的IPython中,它返回 'TerminalInteractiveShell';在Jupyter(包括notebook和qtconsole)中,它返回 'ZMQInteractiveShell';而在普通的Python解释器中则会出错(NameError)。当你启动IPython时,get_ipython() 这个函数默认就可以在全局命名空间中使用。

把它放在一个简单的函数里:

def is_notebook() -> bool:
    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

以上内容是在macOS 10.12和Ubuntu 14.04.4 LTS上,使用Python 3.5.2、IPython 5.1.0和Jupyter 4.2.1进行测试的。

编辑:在2022年,这在更新的Python/IPython/Jupyter/操作系统版本中仍然可以正常工作。

4

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

我们在IPython中尽量让内核不知道连接的是哪种前端,实际上你甚至可以让一个内核同时连接多个不同的前端。即使你可以查看stderr/out的类型来判断你是否在使用ZMQ内核,这也不能保证你在另一边有什么。你甚至可能根本没有任何前端。

你可能应该以一种不依赖前端的方式来编写代码,但如果你想显示不同的内容,可以使用丰富显示系统(链接指向IPython的4.x版本),根据前端显示不同的内容,但选择权在前端,而不是库。

撰写回答