notebook nbviewer examples python ipython ipython-notebook

nbviewer - ¿Cómo puedo verificar si el código se ejecuta en el cuaderno de IPython?



manual jupyter notebook (8)

Estoy usando Django Shell Plus para iniciar IPython, y quería hacer que ''ejecutar en el cuaderno'' esté disponible como un valor de configuración de Django. get_ipython() no está disponible cuando se cargan los ajustes, así que uso esto (que no es a prueba de balas, pero es lo suficientemente bueno para los entornos de desarrollo locales en los que se usa):

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

Tengo un ejemplo de código Python que me gustaría compartir y que debería hacer algo diferente si se ejecuta en el terminal Python / IPython o en el cuaderno IPython

¿Cómo puedo verificar desde mi código Python si se está ejecutando en la notebook IPython?


La pregunta es qué quieres ejecutar de manera diferente.

Hacemos todo lo posible para evitar que el kernel sepa a qué tipo de frontend está conectado, e incluso puede tener un kernel conectado a muchos frontends diferentes al mismo tiempo. Incluso si puede echar un vistazo al tipo de stderr/out para saber si está en un kernel ZMQ o no, no le garantiza lo que tiene en el otro lado. Incluso podrías no tener frontends en absoluto.

Probablemente debería escribir su código de manera independiente en el frontend, pero si desea mostrar diferentes elementos, puede usar el sistema de visualización enriquecido (enlace fijado a la versión 4.x de IPython) para mostrar diferentes elementos según el frontend, pero Frontend elegirá, no la biblioteca.


Lo siguiente captura los casos de https://.com/a/50234148/1491619 sin necesidad de analizar la salida de 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://.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


Lo siguiente funcionó para mis necesidades:

get_ipython().__class__.__name__

Devuelve ''TerminalInteractiveShell'' en un terminal IPython, ''ZMQInteractiveShell'' en Jupyter (notebook AND qtconsole) y falla ( NameError ) en un intérprete Python regular. El método get_python() parece estar disponible en el espacio de nombres global de forma predeterminada cuando se inicia IPython.

Envolviéndolo en una función simple:

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

Lo anterior se probó con Python 3.5.2, IPython 5.1.0 y Jupyter 4.2.1 en macOS 10.12 y Ubuntu 14.04.4 LTS


Para comprobar si estás en un cuaderno, lo cual puede ser importante, por ejemplo, al determinar qué tipo de barra de progreso usar, esto funcionó para mí:

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


Puede verificar si Python está en modo interactivo usando el siguiente fragmento de código [1] :

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

He encontrado este método muy útil porque hago muchos prototipos en el cuaderno. Para propósitos de prueba, uso los parámetros por defecto. De lo contrario, leo los parámetros de sys.argv .

from sys import argv if is_interactive(): params = [<list of default parameters>] else: params = argv[1:]


Que yo sepa, aquí hay 3 tipos de ipython que usaban ipykernel

  1. ipython qtconsole ("qtipython" para abreviar)
  2. IPython en spyder ("spyder" para abreviar)
  3. IPython en el cuaderno jupyter ("jn" para abreviar)

usar ''spyder'' in sys.modules puede distinguir spyder

pero para qtipython y jn son difíciles de distinguir porque

tienen los mismos sys.modules y la misma configuración de IPython: get_ipython().config

Encuentro una diferencia entre qtipython y jn:

primero ejecute os.getpid() en el shell de IPython para obtener el número pid

luego ejecute ps -ef|grep [pid number]

mi qtipython pid es 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

mi jn pid es 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

el diferente de qtipython y jn es el nombre json del ipython, el nombre json de jn es más largo que el qtipython

Por lo tanto, podemos detectar automáticamente todos los entornos Python mediante el siguiente código:

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)

El código fuente está aquí: Detección Python Environment, especialmente Spyder, portátil Jupyter, Qtconsole.py


Recientemente, encontré un error en la notebook Jupyter que necesita una solución, y quería hacer esto sin perder la funcionalidad en otros shells. Me di cuenta de que la solución de Keflavich no funciona en este caso, porque get_ipython() está disponible solo directamente desde el portátil, y no desde módulos importados. Así que encontré una forma de detectar desde mi módulo si se importaba y se usaba desde una notebook Jupyter o no:

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

Los comentarios son apreciados si esto es lo suficientemente robusto.

De manera similar, es posible obtener información sobre el cliente y la versión de IPython también:

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