如何检查代码是否在 IPython 笔记本中执行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15411967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I check if code is executed in the IPython notebook?
提问by Christoph
I have some Python code example I'd like to share that should do something different if executed in the terminal Python / IPython or in the IPython notebook.
我有一些我想分享的 Python 代码示例,如果在终端 Python/IPython 或 IPython 笔记本中执行,它应该会做一些不同的事情。
How can I check from my Python code if it's running in the IPython notebook?
如何检查我的 Python 代码是否在 IPython 笔记本中运行?
采纳答案by Matt
The question is what do you want execute differently.
问题是您希望以不同的方式执行什么。
We do our best in IPython prevent the kernel from knowing to which kind of frontend is connected, and actually you can even have a kernel connected to many differents frontends at the same time. Even if you can take a peek at the type of stderr/outto know wether you are in a ZMQ kernel or not, it does not guaranties you of what you have on the other side. You could even have no frontends at all.
我们在 IPython 中尽最大努力防止内核知道连接到哪种前端,实际上您甚至可以让内核同时连接到许多不同的前端。即使您可以通过查看类型stderr/out来了解您是否在 ZMQ 内核中,它也不能保证您在另一侧拥有什么。你甚至可以根本没有前端。
You should probably write your code in a frontend independent manner, but if you want to display different things, you can use the rich display system (link pinned to version 4.x of IPython)to display different things depending on the frontend, but the frontend will choose, not the library.
您可能应该以独立于前端的方式编写代码,但是如果您想显示不同的内容,您可以使用丰富的显示系统(链接固定到 IPython 4.x 版)根据前端显示不同的内容,但是前端会选择,而不是图书馆。
回答by Till Hoffmann
You can check whether python is in interactivemode with the following snippet [1]:
您可以使用以下代码段[1]检查 python 是否处于交互模式:
def is_interactive():
import __main__ as main
return not hasattr(main, '__file__')
I have found this method very useful because I do a lot of prototyping in the notebook. For testing purposes, I use default parameters. Otherwise, I read the parameters from sys.argv.
我发现这种方法非常有用,因为我在笔记本中做了很多原型设计。出于测试目的,我使用默认参数。否则,我从sys.argv.
from sys import argv
if is_interactive():
params = [<list of default parameters>]
else:
params = argv[1:]
Following the implementation of autonotebook, you can tell whether you are in a notebook using the following code.
按照 的实现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
return True
回答by keflavich
To check if you're in a notebook, which can be important e.g. when determining what sort of progressbar to use, this worked for me:
要检查您是否在笔记本中,这可能很重要,例如在确定使用哪种进度条时,这对我有用:
def in_ipynb():
try:
cfg = get_ipython().config
if cfg['IPKernelApp']['parent_appname'] == 'ipython-notebook':
return True
else:
return False
except NameError:
return False
回答by deeenes
Recently I encountered a bug in Jupyter notebookwhich needs a workaround, and I wanted to do this without loosing functionality in other shells. I realized that keflavich's solutiondoes not work in this case, because get_ipython()is available only directly from the notebook, and not from imported modules. So I found a way to detect from my module whether it is imported and used from a Jupyter notebook or not:
最近我在 Jupyter notebook 中遇到了一个需要解决方法的错误,我想在不丢失其他 shell 中的功能的情况下做到这一点。我意识到keflavich 的解决方案在这种情况下不起作用,因为get_ipython()只能直接从笔记本中获得,而不能从导入的模块中获得。所以我找到了一种方法来检测我的模块是否从 Jupyter notebook 导入和使用:
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
Comments are appreciated if this is robust enough.
如果这足够健壮,我们将不胜感激。
Similar way it is possible to get some info about the client, and IPython version as well:
类似的方式可以获得有关客户端的一些信息,以及 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']
回答by Gustavo Bezerra
The following worked for my needs:
以下为我的需要工作:
get_ipython().__class__.__name__
It returns 'TerminalInteractiveShell'on a terminal IPython, 'ZMQInteractiveShell'on Jupyter (notebook AND qtconsole) and fails (NameError) on a regular Python interpreter. The method get_python()seems to be available in the global namespace by default when IPython is started.
它'TerminalInteractiveShell'在终端 IPython、'ZMQInteractiveShell'Jupyter(笔记本和 qtconsole)上返回,并NameError在常规 Python 解释器上失败 ( )。get_python()当 IPython 启动时,该方法似乎默认在全局命名空间中可用。
Wrapping it in a simple function:
将其包装在一个简单的函数中:
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
The above was tested with Python 3.5.2, IPython 5.1.0 and Jupyter 4.2.1 on macOS 10.12 and Ubuntu 14.04.4 LTS
以上已在 macOS 10.12 和 Ubuntu 14.04.4 LTS 上使用 Python 3.5.2、IPython 5.1.0 和 Jupyter 4.2.1 进行测试
回答by user31415629
I am using Django Shell Plus to launch IPython, and I wanted to make 'running in notebook' available as a Django settings value. get_ipython()is not available when loading settings, so I use this (which is not bulletproof, but good enough for the local development environments it's used in):
我正在使用 Django Shell Plus 来启动 IPython,并且我想让“在笔记本中运行”作为 Django 设置值可用。get_ipython()加载设置时不可用,所以我使用它(这不是防弹的,但对于使用它的本地开发环境来说已经足够了):
import sys
if '--notebook' in sys.argv:
ENVIRONMENT = "notebook"
else:
ENVIRONMENT = "dev"
回答by Yang
As far as I know, Here has 3 kinds of ipython that used ipykernel
据我所知,这里有 3 种使用的 ipython ipykernel
ipython qtconsole("qtipython" for short)- IPython in spyder ("spyder" for short)
- IPython in jupyter notebook ("jn" for short)
ipython qtconsole(简称“qtipython”)- spyder 中的 IPython(简称“spyder”)
- jupyter notebook 中的 IPython(简称“jn”)
use 'spyder' in sys.modulescan distinguish spyder
使用'spyder' in sys.modules可以区分spyder
but for qtipython and jn are hard to distinguish cause
但是对于 qtipython 和 jn 很难区分原因
they have same sys.modulesand same IPython config:get_ipython().config
它们具有相同的sys.modulesIPython 配置:get_ipython().config
I find a different between qtipython and jn:
我发现 qtipython 和 jn 之间存在差异:
first run os.getpid()in IPython shell get the pid number
首先os.getpid()在 IPython shell 中运行获取 pid 号
then run ps -ef|grep [pid number]
然后运行 ps -ef|grep [pid number]
my qtipython pid is 8699
yanglei 8699 8693 4 20:31 ? 00:00:01 /home/yanglei/miniconda2/envs/py3/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-8693.json
我的 qtipython pid 是 8699
yanglei 8699 8693 4 20:31 ? 00:00:01 /home/yanglei/miniconda2/envs/py3/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-8693.json
my jn pid is 8832
yanglei 8832 9788 13 20:32 ? 00:00:01 /home/yanglei/miniconda2/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-ccb962ec-3cd3-4008-a4b7-805a79576b1b.json
我的 jn pid 是 8832
yanglei 8832 9788 13 20:32 ? 00:00:01 /home/yanglei/miniconda2/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-ccb962ec-3cd3-4008-a4b7-805a79576b1b.json
the different of qtipython and jn is the ipython's json name, jn's json name are longer than qtipython's
qtipython 和 jn 的不同是 ipython 的 json 名称,jn 的 json 名称比 qtipython 的要长
so, we can auto detection all Python Environment by following code:
因此,我们可以通过以下代码自动检测所有 Python 环境:
import sys,os
def jupyterNotebookOrQtConsole():
env = 'Unknow'
cmd = 'ps -ef'
try:
with os.popen(cmd) as stream:
if not py2:
stream = stream._stream
s = stream.read()
pid = os.getpid()
ls = list(filter(lambda l:'jupyter' in l and str(pid) in l.split(' '), s.split('\n')))
if len(ls) == 1:
l = ls[0]
import re
pa = re.compile(r'kernel-([-a-z0-9]*)\.json')
rs = pa.findall(l)
if len(rs):
r = rs[0]
if len(r)<12:
env = 'qtipython'
else :
env = 'jn'
return env
except:
return env
pyv = sys.version_info.major
py3 = (pyv == 3)
py2 = (pyv == 2)
class pyi():
'''
python info
plt : Bool
mean plt avaliable
env :
belong [cmd, cmdipython, qtipython, spyder, jn]
'''
pid = os.getpid()
gui = 'ipykernel' in sys.modules
cmdipython = 'IPython' in sys.modules and not gui
ipython = cmdipython or gui
spyder = 'spyder' in sys.modules
if gui:
env = 'spyder' if spyder else jupyterNotebookOrQtConsole()
else:
env = 'cmdipython' if ipython else 'cmd'
cmd = not ipython
qtipython = env == 'qtipython'
jn = env == 'jn'
plt = gui or 'DISPLAY' in os.environ
print('Python Envronment is %s'%pyi.env)
the source code are here:Detection Python Environment, Especially distinguish Spyder, Jupyter notebook, Qtconsole.py
回答by Bob Weigel
The following captures the cases of https://stackoverflow.com/a/50234148/1491619without needing to parse the output of ps
下面捕获https://stackoverflow.com/a/50234148/1491619的情况,无需解析输出ps
def pythonshell():
"""Determine python shell
pythonshell() returns
'shell' (started python on command line using "python")
'ipython' (started ipython on command line using "ipython")
'ipython-notebook' (e.g., running in Spyder or started with "ipython qtconsole")
'jupyter-notebook' (running in a Jupyter notebook)
See also https://stackoverflow.com/a/37661854
"""
import os
env = os.environ
shell = 'shell'
program = os.path.basename(env['_'])
if 'jupyter-notebook' in program:
shell = 'jupyter-notebook'
elif 'JPY_PARENT_PID' in env or 'ipython' in program:
shell = 'ipython'
if 'JPY_PARENT_PID' in env:
shell = 'ipython-notebook'
return shell
回答by Shital Shah
I would recommend avoiding to detect specific frontend because there are too many of them. Instead you can just test if you are running from within iPython environment:
我建议避免检测特定的前端,因为它们太多了。相反,您可以测试是否在 iPython 环境中运行:
def is_running_from_ipython():
from IPython import get_ipython
return get_ipython() is not None
Above will return Falseif you are invoking running_from_ipythonfrom usual python command line. When you invoke it from Jupyter Notebook, JupyterHub, iPython shell, Google Colab etc then it will return True.
False如果您running_from_ipython从通常的 python 命令行调用,上面将返回。当您从 Jupyter Notebook、JupyterHub、iPython shell、Google Colab 等调用它时,它将返回True.
回答by Robert Nowak
Tested for python 3.7.3
测试python 3.7.3
CPython implementations have the name __builtins__available as part of their globals which btw. can be retrieved by the function globals().
If a script is running in an Ipython environment then __IPYTHON__should be an attribute of __builtins__.
The code below therefore returns Trueif run under Ipython or else it gives False
CPython 实现的名称__builtins__可用作其全局变量的一部分,顺便说一句。可以通过函数 globals() 检索。
如果脚本在 Ipython 环境中运行,则__IPYTHON__应该是__builtins__.
因此,True如果在 Ipython 下运行,则下面的代码将返回,否则它会给出False
hasattr(__builtins__,'__IPYTHON__')

