如何检查,如果代码是在IPython的笔记本执行?(How can I check if code

2019-07-21 15:10发布

我有一些Python代码的例子,我想与大家分享,如果在终端的Python / IPython中或在IPython的笔记本电脑执行应该做不同的事情。

我怎样才能从我的Python代码检查,如果它在笔记本电脑的IPython运行?

Answer 1:

现在的问题是你要执行什么不同。

我们尽我们的IPython中最好避免这个问题从认知到那种前端的装置连接,实际上,你甚至可以同时连接多个型动物前端的内核。 即使你可以在类型偷看stderr/out知道无论您是在一个ZMQ内核与否,它不担保你的,你对对方什么。 你甚至可以没有任何前端可言。

你或许应该写在一个前端独立的方式你的代码,但如果你想显示不同的东西,你可以使用丰富的显示系统(链接固定到IPython的4.x版)显示根据前端不同的东西,但前端会选择,而不是图书馆。



Answer 2:

要确定什么样的进度来使用时,请检查您是否在笔记本的时候,它可以是重要的例如,这个工作对我来说:

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


Answer 3:

下面的工作了我的需求:

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测试



Answer 4:

您可以检查是否蟒是使用下面的代码片段交互模式[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:]


Answer 5:

最近我遇到了一个在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']


Answer 6:

以下捕捉的情况下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


Answer 7:

据我所知,这里有3种IPython中所使用的ipykernel

  1. ipython qtconsole ( “qtipython”的简称)
  2. IPython的在Spyder的( “Spyder的” 的简称)
  3. IPython的在jupyter笔记本( “JN” 的简称)

使用'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



Answer 8:

我使用的Django壳牌加推出IPython的,我想使可用“在笔记本上运行”作为Django的设置值。 get_ipython()加载设置时,无法使用,所以我用这个(这是不是刀枪不入,但它使用的地方发展环境不够好):

import sys

if '--notebook' in sys.argv:
    ENVIRONMENT = "notebook"
else:
    ENVIRONMENT = "dev"


Answer 9:

我会建议避免检测特定的前端,因为有太多的人 。 相反,你可以测试,如果你是从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。



文章来源: How can I check if code is executed in the IPython notebook?