tutorial tablas online notebook compiler python debugging emacs ipython pdb

tablas - Depuración paso a paso con IPython



notebook python jupyter (13)

(Actualización del 28 de mayo de 2016) Uso de RealGUD en Emacs

Para cualquiera en Emacs, este hilo muestra cómo lograr todo lo descrito en el OP (y más) usando

  1. un nuevo depurador importante en Emacs llamado RealGUD que puede operar con cualquier depurador (incluido ipdb ).
  2. El paquete Emacs isend-mode .

La combinación de estos dos paquetes es extremadamente poderosa y permite recrear exactamente el comportamiento descrito en el OP y hacer aún más.

Más información sobre el artículo de la wiki de RealGUD para ipdb.

Respuesta original:

Después de haber probado muchos métodos diferentes para depurar Python, incluyendo todo lo mencionado en este hilo, una de mis formas preferidas de depurar Python con IPython es con shells incrustados.

Definición de un shell de IPython incrustado personalizado:

Agregue lo siguiente en una secuencia de comandos a su PYTHONPATH , de modo que el método ipsh() esté disponible.

import inspect # First import the embed function from IPython.terminal.embed import InteractiveShellEmbed from IPython.config.loader import Config # Configure the prompt so that I know I am in a nested (embedded) shell cfg = Config() prompt_config = cfg.PromptManager prompt_config.in_template = ''N.In <//#>: '' prompt_config.in2_template = '' .//D.: '' prompt_config.out_template = ''N.Out<//#>: '' # Messages displayed when I drop into and exit the shell. banner_msg = ("/n**Nested Interpreter:/n" "Hit Ctrl-D to exit interpreter and continue program./n" "Note that if you use %kill_embedded, you can fully deactivate/n" "This embedded instance so it will never turn on again") exit_msg = ''**Leaving Nested interpreter'' # Wrap it in a function that gives me more context: def ipsh(): ipshell = InteractiveShellEmbed(config=cfg, banner1=banner_msg, exit_msg=exit_msg) frame = inspect.currentframe().f_back msg = ''Stopped at {0.f_code.co_filename} at line {0.f_lineno}''.format(frame) # Go back one level! # This is needed because the call to ipshell is inside the function ipsh() ipshell(msg,stack_depth=2)

Entonces, cada vez que quiero depurar algo en mi código, ipsh() en la ubicación donde necesito hacer la inspección de objetos, etc. Por ejemplo, digamos que quiero depurar my_function continuación

Utilizándolo:

def my_function(b): a = b ipsh() # <- This will embed a full-fledged IPython interpreter a = 4

y luego invoca my_function(2) de una de las siguientes maneras:

  1. Ya sea ejecutando un programa Python que invoca esta función desde un shell Unix
  2. O invocándolo directamente desde IPython

Independientemente de cómo lo invoque, el intérprete se detiene en la línea que dice ipsh() . Una vez que haya terminado, puede hacer Ctrl-D y Python reanudará la ejecución (con las actualizaciones de variables que haya realizado). Tenga en cuenta que, si ejecuta el código de un IPython regular, el shell de IPython (caso 2 anterior), el nuevo shell de IPython estará anidado dentro del que lo invocó, lo que está perfectamente bien, pero es bueno tenerlo en cuenta. En cualquier caso, una vez que el intérprete se detiene en la ubicación de ipsh , puedo inspeccionar el valor de a (que es 2 ), ver qué funciones y objetos se definen, etc.

El problema:

La solución anterior puede usarse para que Python se detenga en el lugar que desee en su código y luego lo lleve a un intérprete de IPython completamente desarrollado. Lamentablemente, no le permite agregar o quitar puntos de interrupción una vez que invoca el script, lo cual es muy frustrante. En mi opinión, esto es lo único que impide que IPython se convierta en una gran herramienta de depuración para Python.

Lo mejor que puedes hacer por ahora:

Una solución consiste en colocar ipsh() a priori en las diferentes ubicaciones donde desea que el intérprete de Python inicie un shell IPython (es decir, un breakpoint ). A continuación, puede "saltar" entre diferentes "puntos de interrupción" predefinidos y codificados con Ctrl-D , que saldría del intérprete de IPython incrustado actual y se detendrá cuando el intérprete toque la próxima llamada a ipsh() .

Si realiza esta ruta, una forma de salir del "modo de depuración" e ignorar todos los puntos de interrupción posteriores, es usar ipshell.dummy_mode = True que hará que Python ignore cualquier instancia posterior del objeto ipshell que creamos anteriormente.

Según lo que he leído, hay dos formas de depurar código en Python:

  • Con un depurador tradicional como pdb o ipdb . Esto admite comandos como c para continue , n para step-over a step-over , s para step-into a step-into etc.), pero no tiene acceso directo a un shell IPython que puede ser extremadamente útil para la inspección de objetos.

  • Usando IPython al incrustar un shell IPython en su código. Puedes hacerlo from ipython import embed , y luego usar embed() en tu código. Cuando su programa / script golpea una instrucción embed() , se le deja caer en un shell de IPython. Esto permite la inspección completa de los objetos y la prueba del código de Python usando todos los recursos de IPython. Sin embargo, al usar embed() no puede seguir paso a paso a través del código con atajos de teclado útiles.

¿Hay alguna manera de combinar lo mejor de ambos mundos? Es decir

  1. Sé capaz de pasar paso a paso a través de tu código con prácticos atajos de teclado pdb / ipdb.
  2. En cualquier paso de este tipo (por ejemplo, en una declaración dada), tenga acceso a un shell de IPython en toda regla.

Depuración de IPython como en MATLAB:

Un ejemplo de este tipo de "depuración mejorada" se puede encontrar en MATLAB, donde el usuario siempre tiene acceso completo al motor / shell MATLAB, y puede seguir paso a paso a través de su código, definir puntos de interrupción condicionales, etc. Lo que he discutido con otros usuarios, esta es la característica de depuración que las personas más extrañan al pasar de MATLAB a IPython.

Depuración de IPython en Emacs y otros editores:

No quiero que la pregunta sea demasiado específica, pero trabajo principalmente en Emacs, por lo que me pregunto si hay alguna forma de incorporar esta funcionalidad. Idealmente , Emacs (o el editor) le permitiría al programador establecer puntos de interrupción en cualquier punto del código y comunicarse con el intérprete o el depurador para que se detenga en la ubicación que elija y llevarlo a un intérprete completo de IPython en esa ubicación.


¿Has probado este consejo ?

O mejor aún, usa ipython y llama:

from IPython.Debugger import Tracer; debug_here = Tracer()

entonces solo puedes usar

debug_here()

cada vez que quiera establecer un punto de interrupción


¿Qué pasa con ipdb.set_trace ()? En tu código:

import ipdb; ipdb.set_trace()

Esto permite una inspección completa de su código, y usted tiene acceso a comandos tales como c (continuar), n (ejecutar la siguiente línea), s (ingresar al método en el punto) y así sucesivamente.

Vea el repositorio de ipdb y una lista de comandos . IPython ahora se llama (editar: parte de) Jupyter .

ps: tenga en cuenta que un comando ipdb tiene prioridad sobre el código python. Entonces para escribir la list(foo) necesitarías print list(foo) .

Además, si le gusta el indicador de ipython (sus modos emacs y vim, historial, terminaciones, ...) es fácil obtener lo mismo para su proyecto, ya que está basado en el kit de herramientas de solicitud de Python .


Desde python 3.2, tiene el comando interact , que le da acceso al espacio de comando completo de python / ipython.


Ejecutar desde el interior del shell IPython de Emacs y establecer el punto de interrupción a través de pdb.set_trace () debería funcionar.

Comprobado con python-mode.el, Mx ipython RET, etc.


El Pyzo IDE tiene capacidades similares a las que el OP solicitó. No tiene que comenzar en modo de depuración. De forma similar a MATLAB, los comandos se ejecutan en el shell. Cuando configura un punto de interrupción en alguna línea de código fuente, el IDE detiene la ejecución allí y puede depurar y emitir también comandos regulares de IPython.

Sin embargo, parece que el step-into no funciona (¿todavía?) Funciona bien (es decir, detenerse en una línea y luego entrar en otra función) a menos que configure otro punto de interrupción.

Aún así, viniendo de MATLAB, esta parece ser la mejor solución que he encontrado.


La respuesta correcta, fácil, fría y exacta para la pregunta es usar% run macro con el indicador -d.

In [4]: run -d myscript.py NOTE: Enter ''c'' at the ipdb> prompt to continue execution. > /cygdrive/c/Users/mycodefolder/myscript.py(4)<module>() 2 3 ----> 4 a=1 5 b=2


Nadie mencionó aún la bandera %pdb IPython. Simplemente llame a %pdb en IPython y, cuando ocurra un error, se eliminará automáticamente a ipdb . Si bien no tienes el paso inmediatamente, estás en ipdb luego.

Esto facilita la depuración de funciones individuales, ya que solo puede cargar un archivo con %load y luego ejecutar una función. Podría forzar un error con una assert en la posición correcta.


Parece que el enfoque en la respuesta de @ gaborous está en desuso .

El nuevo enfoque parece ser:

from IPython.core import debugger debug = debugger.Pdb().set_trace def buggy_method(): debug()


Prefijo de un "!" El símbolo de comandos que escribe en pdb parece tener el mismo efecto que hacer algo en un shell de IPython. Esto funciona para acceder a ayuda para una determinada función, o incluso nombres de variables. Quizás esto te ayude en cierta medida. Por ejemplo,

ipdb> help(numpy.transpose) *** No help on (numpy.transpose)

Pero! Help (numpy.transpose) le dará la página de ayuda esperada en numpy.transpose. De manera similar, para nombres de variables, digamos que tiene una variable l, escribir "l" en pdb enumera el código, pero! L imprime el valor de l.


Puede iniciar la sesión de IPython desde Pudr y volver a la sesión de depuración como desee.

Por cierto, ipdb está usando IPython detrás de escena y realmente puedes usar la funcionalidad de IPython como TAB completa y comandos mágicos (el que comienza con % ). Si está bien con ipdb, puede iniciarlo desde IPython usando comandos como %run y %debug . la sesión ipdb es mejor que la simple IPython, en el sentido de que puede subir y bajar en el seguimiento de pila, etc. ¿Qué falta en ipdb para "inspección de objetos"?

Además, python.el incluido con Emacs> = 24.3 tiene buen soporte para ipdb.


Si escribe exit () en la consola embed (), el código continúa y va a la siguiente línea embed ().


Una opción es usar un IDE como Spyder que debería permitirle interactuar con su código mientras se depura (usando una consola IPython, de hecho). De hecho, Spyder es muy parecida a MATLAB, y supongo que fue intencional. Eso incluye inspectores variables, edición variable, acceso integrado a la documentación, etc.