6.1. Depuración con pdb¶
En este tutorial se exploran herramientas que ayudan a entender tu código: depuración para encontrar y corregir bugs (errores).
El depurador python, pdb, te permite inspeccionar tu código de forma interactiva.
Te permite:
Ver el código fuente.
Ir hacia arriba y hacia abajo del punto donde se ha producido un error.
Inspeccionar valores de variables.
Modificar valores de variables.
Establecer
breakpoints
(punto de parada del proceso).
6.1.1. Invocando al depurador¶
Formas de lanzar el depurador:
Postmortem, lanza el depurador después de que se hayan producido errores.
Lanza el módulo con el depurador.
Llama al depurador desde dentro del módulo.
6.1.1.1. Postmortem¶
Situación: Estás trabajando en ipython
y obtienes un error (traceback).
En este caso esta depurando el archivo index_error.py
. Cuando lo ejecutes verás como se lanza una excepción IndexError. Escribe %debug
y entrarás en el depurador.
In [1]: %run index_error.py
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
/home/macagua/python/entrenamiento/index_error.py in <module>()
6
7 if __name__ == '__main__':
----> 8 index_error()
9
/home/macagua/python/entrenamiento/index_error.py in index_error()
3 def index_error():
4 lst = list('foobar')
----> 5 print(lst[len(lst)])
6
7 if __name__ == '__main__':
IndexError: list index out of range
In [2]: %debug
> /home/macagua/python/entrenamiento/index_error.py(5)index_error()
4 lst = list('foobar')
----> 5 print(lst[len(lst)])
6
ipdb> list
1 """Small snippet to raise an IndexError."""
2
3 def index_error():
4 lst = list('foobar')
----> 5 print(lst[len(lst)])
6
7 if __name__ == '__main__':
8 index_error()
9
ipdb> len(lst)
6
ipdb> print(lst[len(lst)-1])
r
ipdb> quit
In [3]:
6.1.1.2. Ejecución paso a paso¶
Situación: Crees que existe un error en un módulo pero no estás seguro donde.
Por ejemplo, esta intentado depurar wiener_filtering.py
.
A pesar de que el código se ejecuta, observa que el filtrado no se
está haciendo correctamente.
-
Ejecuta el script en IPython con el depurador usando
%run -d wiener_filtering.py
:In [1]: %run -d wiener_filtering.py *** Blank or comment *** Blank or comment *** Blank or comment Breakpoint 1 at /home/macagua/python/entrenamiento/wiener_filtering.py:4 NOTE: Enter 'c' at the ipdb> prompt to start your script. > <string>(1)<module>()
-
Coloca un breakpoint en la línea 34 usando
b 34
:ipdb> n > /home/macagua/python/entrenamiento/wiener_filtering.py(4)<module>() 3 1---> 4 import numpy as np 5 import scipy as sp ipdb> b 34 Breakpoint 2 at /home/macagua/python/entrenamiento/wiener_filtering.py:34
-
Continua la ejecución hasta el siguiente breakpoint con
c(ont(inue))
:ipdb> c > /home/macagua/python/entrenamiento/wiener_filtering.py(34)iterated_wiener() 33 """ 2--> 34 noisy_img = noisy_img 35 denoised_img = local_mean(noisy_img, size=size)
-
Da pasos hacia adelante y detrás del código con
n(ext)
ys(tep)
.next
salta hasta la siguiente declaración en el actual contexto de ejecución mientras questep
se moverá entre los contextos en ejecución, i.e. permitiendo explorar dentro de llamadas a funciones:ipdb> s > /home/macagua/python/entrenamiento/wiener_filtering.py(35)iterated_wiener() 2 34 noisy_img = noisy_img ---> 35 denoised_img = local_mean(noisy_img, size=size) 36 l_var = local_var(noisy_img, size=size) ipdb> n > /home/macagua/python/entrenamiento/wiener_filtering.py(36)iterated_wiener() 35 denoised_img = local_mean(noisy_img, size=size) ---> 36 l_var = local_var(noisy_img, size=size) 37 for i in range(3):
-
Muévete unas pocas líneas y explora las variables locales:
ipdb> n > /home/macagua/python/entrenamiento/wiener_filtering.py(37)iterated_wiener() 36 l_var = local_var(noisy_img, size=size) ---> 37 for i in range(3): 38 res = noisy_img - denoised_img ipdb> print(l_var) [[5868 5379 5316 ..., 5071 4799 5149] [5013 363 437 ..., 346 262 4355] [5379 410 344 ..., 392 604 3377] ..., [ 435 362 308 ..., 275 198 1632] [ 548 392 290 ..., 248 263 1653] [ 466 789 736 ..., 1835 1725 1940]] ipdb> print(l_var.min()) 0
Oh dear, solo ve entero y variación 0. Aquí está nuestro error, estamos haciendo aritmética con enteros.
6.1.1.3. Otras formas de comenzar una depuración¶
-
Lanzar una excepción «break point» a lo pobre
Si encuentras tedioso el tener que anotar el número de línea para colocar un break point, puedes lanzar una excepción en el punto que quieres inspeccionar y usar la “magia”
%debug
deipython
. Destacar que en este caso no puedes moverte por el código y continuar después la ejecución. -
Depurando fallos de pruebas usando nosetests
Puede ejecutar
nosetests --pdb
para saltar a la depuración post-mortem de excepciones ynosetests --pdb-failure
para inspeccionar los fallos de pruebas usando el depurador.Además, puedes usar la interfaz IPython para el depurador en nose usando el plugin de nose ipdbplugin. Puede, entonces, pasar las opciones
--ipdb
y--ipdb-failure
a los nosetests. -
Llamando explícitamente al depurador
Inserta la siguiente línea donde quieres que salte el depurador:
1 2 3
import pdb pdb.set_trace()
Advertencia
Cuando se ejecutan nosetests
, se captura la salida y parecerá
que el depurador no está funcionando. Para evitar esto simplemente ejecuta
los nosetests
con la etiqueta -s
.
6.1.2. Comandos del depurador e interacciones¶
|
Lista el código en la posición actual |
|
Paso arriba de la llamada a la pila (call stack) |
|
Paso abajo de la llamada a la pila ((call stack) |
|
Ejecuta la siguiente línea (no va hacia abajo en funciones nuevas) |
|
Ejecuta la siguiente declaración (va hacia abajo en las nuevas funciones) |
|
Muestra el call stack |
|
Muestra las variables locales |
|
Ejecuta el comando Python proporcionado (en oposición a comandos pdb) |
Advertencia
Los comandos de depuración no son código Python
No puedes nombrar a las variables de la forma que quieras. Por ejemplo, si esta dentro del depurador no podrá sobrescribir a las variables con el mismo y, por tanto, habrá que usar diferentes nombres para las variables cuando este tecleando código en el depurador.
6.1.3. Obteniendo ayuda dentro del depurador¶
Teclea h
o help
para acceder a la ayuda interactiva:
ipdb> help
Documented commands (type help <topic>):
========================================
EOF bt cont enable jump pdef r tbreak w
a c continue exit l pdoc restart u whatis
alias cl d h list pinfo return unalias where
args clear debug help n pp run unt
b commands disable ignore next q s until
break condition down j p quit step up
Miscellaneous help topics:
==========================
exec pdb
Undocumented commands:
======================
retval rv
Importante
Usted puede descargar el código usado en esta sección haciendo clic en los
siguientes enlaces: index_error.py
y wiener_filtering.py
.
Adicional se incluye otro código de ejemplo muy simple
funcion_a_depurar.py
usando la función set_trace()
del paquete pdb
.
Truco
Para ejecutar el código index_error.py
, wiener_filtering.py
y funcion_a_depurar.py
, abra una consola de comando, acceda al directorio
donde se encuentra ambos programas:
leccion6/
├── index_error.py
├── wiener_filtering.py
└── funcion_a_depurar.py
Si tiene la estructura de archivo previa, entonces ejecute por separado cada comando:
$ python index_error.py
$ python wiener_filtering.py
$ python funcion_a_depurar.py
Ver también
Consulte la sección de lecturas suplementarias del entrenamiento para ampliar su conocimiento en esta temática.
¿Cómo puedo ayudar?
¡Mi soporte está aquí para ayudar!
Mi horario de oficina es de lunes a sábado, de 9 AM a 5 PM. GMT-4 - Caracas, Venezuela.
La hora aquí es actualmente 7:35 PM GMT-4.
Mi objetivo es responder a todos los mensajes dentro de un día hábil.
