Python para principiantes

10.2. Módulos para el programador

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.


Copyright (c) 2011-2013 Eugenia Bahit. La copia y redistribución de esta página se permite bajo los términos de la licencia Creative Commons Atribución NoComercial SinDerivadas 3.0 Unported siempre que se conserve esta nota de copyright.