我有一些Python代码的例子,我想与大家分享,如果在终端的Python / IPython中或在IPython的笔记本电脑执行应该做不同的事情。
我怎样才能从我的Python代码检查,如果它在笔记本电脑的IPython运行?
我有一些Python代码的例子,我想与大家分享,如果在终端的Python / IPython中或在IPython的笔记本电脑执行应该做不同的事情。
我怎样才能从我的Python代码检查,如果它在笔记本电脑的IPython运行?
现在的问题是你要执行什么不同。
我们尽我们的IPython中最好避免这个问题从认知到那种前端的装置连接,实际上,你甚至可以同时连接多个型动物前端的内核。 即使你可以在类型偷看stderr/out
知道无论您是在一个ZMQ内核与否,它不担保你的,你对对方什么。 你甚至可以没有任何前端可言。
你或许应该写在一个前端独立的方式你的代码,但如果你想显示不同的东西,你可以使用丰富的显示系统(链接固定到IPython的4.x版)显示根据前端不同的东西,但前端会选择,而不是图书馆。
要确定什么样的进度来使用时,请检查您是否在笔记本的时候,它可以是重要的例如,这个工作对我来说:
def in_ipynb():
try:
cfg = get_ipython().config
if cfg['IPKernelApp']['parent_appname'] == 'ipython-notebook':
return True
else:
return False
except NameError:
return False
下面的工作了我的需求:
get_ipython().__class__.__name__
它返回'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
以上是在MacOS 10.12和Ubuntu 14.04.4 LTS与Python 3.5.2,5.1.0的IPython和Jupyter 4.2.1测试
您可以检查是否蟒是使用下面的代码片段交互模式[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:]
最近我遇到了一个在Jupyter笔记本的bug这需要一个解决办法,我想这样做没有其他炮弹失去功能。 我意识到, 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
如果这是足够强大的评论表示赞赏。
类似的方式,有可能获得有关客户,并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']
以下捕捉的情况下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
据我所知,这里有3种IPython中所使用的ipykernel
ipython qtconsole
( “qtipython”的简称) 使用'spyder' in sys.modules
可以区分spyder的
但对于qtipython和JN是很难区分的原因
他们有相同的sys.modules
和相同的IPython配置: get_ipython().config
我觉得qtipython和JN之间的不同:
第一次运行os.getpid()
中的IPython Shell得到PID号
然后运行ps -ef|grep [pid number]
我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
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
我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
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
qtipython和JN的不同是IPython中的JSON名字,JN的JSON名字比qtipython的长
这样,我们就可以自动检测所有的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)
的源代码在这里: 检测Python的环境,特别是区分的Spyder,Jupyter笔记本,Qtconsole.py
我使用的Django壳牌加推出IPython的,我想使可用“在笔记本上运行”作为Django的设置值。 get_ipython()
加载设置时,无法使用,所以我用这个(这是不是刀枪不入,但它使用的地方发展环境不够好):
import sys
if '--notebook' in sys.argv:
ENVIRONMENT = "notebook"
else:
ENVIRONMENT = "dev"
我会建议避免检测特定的前端,因为有太多的人 。 相反,你可以测试,如果你是从IPython的环境中运行:
def is_running_from_ipython():
from IPython import get_ipython
return get_ipython() is None
如果您正在调用上面会返回True running_from_ipython
从普通的Python命令行。 当您从Jupyter笔记本,JupyterHub,IPython的壳,谷歌Colab等调用它,然后它会返回True。