web-dev-qa-db-de.com

Wie kann ich überprüfen, ob im IPython-Notebook Code ausgeführt wird?

Ich habe ein paar Python-Codebeispiele, die ich mitteilen möchte, die etwas anderes machen sollten, wenn sie im Terminal Python/IPython oder im IPython-Notebook ausgeführt werden.

Wie kann ich anhand meines Python-Codes überprüfen, ob er im IPython-Notebook ausgeführt wird?

49
Christoph

Die Frage ist, was wollen Sie anders ausführen.

Wir tun unser Bestes in IPython, um zu verhindern, dass der Kernel weiß, an welche Art von Frontend angeschlossen ist, und tatsächlich können Sie sogar einen Kernel gleichzeitig mit vielen verschiedenen Frontends verbunden haben. Selbst wenn Sie einen Blick auf die Art von stderr/out werfen können, um zu wissen, ob Sie sich in einem ZMQ-Kernel befinden oder nicht, garantiert er Ihnen nicht, was Sie auf der anderen Seite haben. Sie könnten sogar gar keine Frontends haben.

Sie sollten Ihren Code wahrscheinlich in einer vom Frontend unabhängigen Art und Weise schreiben, aber wenn Sie verschiedene Dinge anzeigen möchten, können Sie das rich-Anzeigesystem verwenden (Verknüpfung mit Version 4.x von IPython) , um je nach dem verschiedene Dinge anzuzeigen Frontend, aber das Frontend wählt, nicht die Bibliothek.

10
Matt

Um zu überprüfen, ob Sie sich in einem Notizbuch befinden, kann dies wichtig sein, z. Bei der Festlegung, welche Art von Fortschrittsbalken verwendet werden soll, hat dies für mich funktioniert

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

Folgendes arbeitete für meine Bedürfnisse:

get_ipython().__class__.__name__

Es gibt 'TerminalInteractiveShell' für ein Terminal-IPython, 'ZMQInteractiveShell' für Jupyter (Notizbuch UND qtconsole) und schlägt fehl (NameError) für einen normalen Python-Interpreter. Die Methode get_python() scheint beim Start von IPython standardmäßig im globalen Namespace verfügbar zu sein.

Umhüllen mit einer einfachen Funktion:

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

Das obige wurde mit Python 3.5.2, IPython 5.1.0 und Jupyter 4.2.1 auf macOS 10.12 und Ubuntu 14.04.4 LTS getestet

21
Gustavo Bezerra

Sie können mit dem folgenden Snippet [1] prüfen, ob sich Python im interactive -Modus befindet:

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

Ich habe diese Methode sehr nützlich gefunden, weil ich viel Prototyping im Notebook durchführe. Zu Testzwecken verwende ich Standardparameter. Ansonsten lese ich die Parameter von sys.argv.

from sys import argv

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

Vor kurzem bin ich auf einen Fehler in Jupyter Notebook gestoßen, der eine Problemumgehung erfordert, und ich wollte dies tun, ohne die Funktionalität in anderen Shells zu verlieren. Mir wurde klar, dass keflavichs Lösung in diesem Fall nicht funktioniert, da get_ipython() nur direkt vom Notebook aus verfügbar ist und nicht von importierten Modulen. So fand ich einen Weg, um von meinem Modul aus zu erkennen, ob es von einem Jupyter-Notebook importiert und verwendet wird oder nicht:

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

Kommentare sind erwünscht, wenn dies robust genug ist.

Auf ähnliche Weise ist es möglich, Informationen über den Client und die IPython-Version zu erhalten:

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']
10
deeenes

Soweit ich weiß, hat Here 3 Arten von Ipython, die ipykernel verwendet haben.

  1. ipython qtconsole (kurz "qtipython")
  2. IPython im Spyder (kurz "Spyder")
  3. IPython in einem Jupyter-Notebook (kurz "jn")

verwenden Sie 'spyder' in sys.modules kann Spyder unterscheiden

aber für qtipython und jn ist die Ursache schwer zu unterscheiden

sie haben die gleiche sys.modules und dieselbe IPython-Konfiguration: get_ipython().config

Ich finde einen Unterschied zwischen qtipython und jn:

führen Sie zunächst os.getpid() in der IPython-Shell aus, um die PID-Nummer zu erhalten

dann ps -ef|grep [pid number] ausführen

mein qtipython pid ist 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

mein jn pid ist 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

der Unterschied zwischen qtipython und jn ist der Json-Name des Ipythons, der Json-Name von Jn ist länger als der von Qtipython

so können wir alle Python-Umgebungen durch folgenden Code automatisch erkennen:

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)

der Quellcode ist hier: Erkennung Python-Umgebung, besonders unterscheiden sich Spyder, Jupyter Notebook, Qtconsole.py

1
Yang

Im Folgenden werden die Fälle von https://stackoverflow.com/a/50234148/1491619 erfasst, ohne dass die Ausgabe von ps analysiert werden muss.

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
1
Bob Weigel

Ich würde empfehlen, das Erkennen eines bestimmten Frontends zu vermeiden, da es zu viele gibt. Stattdessen können Sie einfach testen, ob Sie in einer iPython-Umgebung ausgeführt werden:

def is_running_from_ipython():
    from IPython import get_ipython
    return get_ipython() is None

Oben wird True zurückgegeben, wenn Sie running_from_ipython über die normale Python-Befehlszeile aufrufen. Wenn Sie es über Jupyter Notebook, JupyterHub, iPython Shell, Google Colab usw. aufrufen, wird True zurückgegeben.

0
Shital Shah

Ich benutze Django Shell Plus, um IPython zu starten, und ich wollte "Laufen im Notebook" als Django-Einstellungswert verfügbar machen. get_ipython() steht beim Laden von Einstellungen nicht zur Verfügung. Daher verwende ich Folgendes (das ist nicht kugelsicher, aber gut genug für die lokalen Entwicklungsumgebungen, in denen es verwendet wird):

import sys

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