如何检查代码是否在IPython笔记本中执行?
我有一些Python代码示例想分享,这段代码在终端的Python或IPython中执行时应该做不同的事情,而在IPython笔记本中执行时又是另一种情况。
我该如何在我的Python代码中检查它是否在IPython笔记本中运行呢?
18 个回答
你可以用下面的代码来检查 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
以下内容满足了我的需求:
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/操作系统版本中仍然可以正常工作。
问题是你想要以不同的方式执行什么。
我们在IPython中尽量让内核不知道连接的是哪种前端,实际上你甚至可以让一个内核同时连接多个不同的前端。即使你可以查看stderr/out
的类型来判断你是否在使用ZMQ内核,这也不能保证你在另一边有什么。你甚至可能根本没有任何前端。
你可能应该以一种不依赖前端的方式来编写代码,但如果你想显示不同的内容,可以使用丰富显示系统(链接指向IPython的4.x版本),根据前端显示不同的内容,但选择权在前端,而不是库。