10.2.1. Debuguear código con Pdb
El módulo pdb
nos sirve para controlar paso a paso, la ejecución de nuestros programas. Pdb
se utiliza solo para debuguear y su utilidad consiste en permitirnos conocer el lugar exacto y el por qué, nuestro script falla.
Imagina que tienes un archivo que genera errores y no logras descubrir la solución. Puedes importar el módulo pdb
y hacer una llamada a pdb.Pdb().set_trace()
en la línea, a partir de la cuál, deseas que tu script comience a "caminar paso a paso" para así, descubrir el error:
# -*- coding: utf-8 -*-
import pdb
from subprocess import call, Popen, PIPE
# Limpiar la pantalla
call("clear")
pdb.Pdb().set_trace()
proceso = Popen(['ls', '-lha'], stdout=PIPE, stderr=PIPE)
error_encontrado = proceso.stderr.read()
proceso.stderr.close()
listado = proceso.stdout.read()
proceso.stdout.close()
if not error_encontrado:
print listado
else:
print "Se produjo el siguiente error:\n%s" % error_encontrado
A partir de la línea donde pdb.Pdb().set_trace()
se encuentra, al ejecutar python tu_archivo.py
, Pdb
comenzará a ejecutar tu archivo línea por línea, esperando tu respuesta. Por ejemplo, en el código anterior, tras la ejecución del archivo, la pantalla se limpiará y Pdb
comenzará a actuar, mostrándote la línea que sigue:
-> proceso = Popen(['ls', '-lha'], stdout=PIPE, stderr=PIPE)
(Pdb)
Pdb
estará esperando tu orden para continuar. Entre las órdenes más usuales, puedes indicar:
n (next) ejecuta el código mostrado y salta a la siguiente línea de tu archivo
s (step) te mostrará paso a paso el camino recorrido
hasta poder ejecutar la siguiente línea de tu archivo
c (continue) ejecuta el archivo hasta encontrar un punto de quiebre
q (quit) abandonar el debugger
Pero no solo un comando, puede ser ordenado a Pdb
. También es posible, depurar el código de tu archivo, ejecutando alguna instrucción:
-> listado = proceso.stdout.read()
(Pdb) n
> /home/eugenia/Cursos/Python para Principiantes/Módulo
5/sources/subprocess_examples/examples.py(13)<module>()
-> proceso.stdout.close()
(Pdb) listado.upper()
'TOTAL 12K\nDRWXRWXR-X 2 EUGENIA EUGENIA 4,0K 2012-07-07 17:34 .\nDRWXRWXR-X 8
EUGENIA EUGENIA 4,0K 2012-07-07 17:34 ..\n-RW-RW-R-- 1 EUGENIA EUGENIA 429
2012-07-07 20:48 EXAMPLES.PY\n'
(Pdb)
Nota Puedes obtener más información sobre Pdb
ingresando en la documentación oficial.
10.2.2. Documentar tu app con pydoc
Con tan solo colocar los docstrings correspondientes en cada módulo y/o función de tu Python app, ejecutar en la terminal pydoc tu_app
será suficiente para acceder a toda la documentación:
~$ pydoc tienda Help on package tienda: NAME tienda FILE /home/eugenia/pythonapps/tienda/__init__.py PACKAGE CONTENTS __main__ administracion (package) buscador (package) core (package)
Alternativamente, también puedes obtener la documentación en formato HTML. Para ello, deberás ejecutar: pydoc -w nombre_del_modulo
Otra alternativa, es iniciar un servidor Web local, que te permita navegar por la documentación de tu app. Para ello, simplemente ejecuta pydoc -p n
(donde n
, es el número del puerto por el cual accederás. Por ejemplo, pydoc -p 8080
inicia el servidor en http://localhost:8080/).
10.2.3. Probar el código antes de enviarlo a producción con doctest
El módulo doctest
de Python, nos permite indicar fragmentos de código en los comentarios de nuestros módulos, que emulen instrucciones del intérprete interactivo, ejecutándolas de forma tal, que podamos automatizar las pruebas de nuestra aplicación.
import doctest
def sumar_dos_numeros(a, b):
"""Suma dos números y retorna su resultado
Argumentos:
a -- primer sumando
b -- segundo sumando
Test:
>>> sumar_dos_numeros(25, 10)
35
>>> sumar_dos_numeros(30, 20)
50
"""
return a + b
if __name__ == "__main__":
doctest.testmod()
Si vemos el texto debajo de Test:
, luce como el intérprete interactivo. Aquí estoy invocando a la función:
>>> sumar_dos_numeros(25, 10)
Y debajo, estoy simulando el resultado que arrojaría en el intérprete interactivo. Esto, será interpretado por doctest
, como el resultado esperado:
35
Para correr los test, solo bastará con ejecutar:
~$ python modulo.py -v
Y obtendremos un resultado similar a:
eugenia@cochito:~/pythonapps/doctest_examples$ python suma.py -v
Trying:
sumar_dos_numeros(25, 10)
Expecting:
35
ok
Trying:
sumar_dos_numeros(30, 20)
Expecting:
50
ok
1 items had no tests:
__main__
1 items passed all tests:
2 tests in __main__.sumar_dos_numeros
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
Nota Puedes obtener más información sobre doctest
visita la documentación oficial.