Depurar aplicaciones de Python con el m贸dulo PDB

    Introducci贸n

    En este tutorial, aprenderemos a usar Python PDB m贸dulo para depurar aplicaciones Python. La depuraci贸n se refiere al proceso de eliminar errores de software y hardware de una aplicaci贸n de software. PDB significa “Python Debugger” y es un depurador de c贸digo fuente interactivo integrado con una amplia gama de caracter铆sticas, como pausar un programa, ver valores de variables en instancias espec铆ficas, cambiar esos valores, etc.

    En este art铆culo, cubriremos las funcionalidades m谩s utilizadas del m贸dulo PDB.

    Antecedentes

    La depuraci贸n es una de las actividades m谩s desagradables en el desarrollo de software y, al mismo tiempo, es una de las tareas m谩s importantes en el ciclo de vida del desarrollo de software. En alg煤n momento, cada programador tiene que depurar su c贸digo, a menos que est茅 desarrollando una aplicaci贸n de software muy b谩sica.

    Hay muchas formas diferentes de depurar una aplicaci贸n de software. Un m茅todo muy utilizado es usar las declaraciones “imprimir” en diferentes instancias de su c贸digo para ver qu茅 est谩 sucediendo durante la ejecuci贸n. Sin embargo, este m茅todo tiene muchos problemas, como la adici贸n de c贸digo adicional que se utiliza para imprimir los valores de las variables, etc. Si bien este enfoque puede funcionar para un programa peque帽o, el seguimiento de estos cambios de c贸digo en una aplicaci贸n grande con muchas l铆neas de c贸digo , repartidos en diferentes archivos, puede convertirse en un gran problema. El depurador nos resuelve ese problema. Nos ayuda a encontrar las fuentes de error en una aplicaci贸n usando comandos externos, por lo tanto, no hay cambios en el c贸digo.

    Nota: Como se mencion贸 anteriormente, PDB es un m贸dulo Python integrado, por lo que no es necesario instalarlo desde una fuente externa.

    Comandos de teclado

    Para comprender los principales comandos o herramientas que tenemos a nuestra disposici贸n en PDB, consideremos un programa b谩sico de Python y luego intentemos depurarlo usando comandos PDB. De esta forma, veremos con un ejemplo qu茅 hace exactamente cada comando.

    # Filename: calc.py
    
    operators = ['+', '-', '*', "https://Pharos.sh.com/"]
    numbers = [10, 20]
    
    def calculator():
        print("Operators available: ")
        for op in operators:
            print(op)
    
        print("Numbers to be used: ")
        for num in numbers:
            print(num)
    
    def main():
        calculator()
    
    main()
    

    Aqu铆 est谩 el resultado del script anterior:

    Operators available:
    +
    -
    *
    /
    Numbers to be used:
    10
    20
    

    No he agregado ning煤n comentario en el c贸digo anterior, ya que es amigable para principiantes y no involucra conceptos complejos o sintaxis en absoluto. No es importante intentar entender la “tarea” que logra este c贸digo, ya que su prop贸sito era incluir ciertas cosas para que todos los comandos de PDB pudieran probarse en 茅l. Muy bien entonces, 隆comencemos!

    El uso de PDB requiere el uso de la interfaz de l铆nea de comandos (CLI), por lo que debe ejecutar su aplicaci贸n desde el terminal o el s铆mbolo del sistema.

    Ejecute el siguiente comando en su CLI:

    $ python -m pdb calc.py
    

    En el comando anterior, el nombre de mi archivo es “calc.py”, por lo que deber谩 insertar su propio nombre de archivo aqu铆.

    Nota: Los -m es una bandera y notifica al ejecutable de Python que un m贸dulo necesita ser importado; esta bandera es seguida por el nombre del m贸dulo, que en nuestro caso es pdb.

    La salida del comando se ve as铆:

    > /Users/junaid/Desktop/calc.py(3)<module>()
    -> operators = [ '+', '-', '*', "https://Pharos.sh.com/" ]
    (Pdb)
    

    La salida siempre tendr谩 la misma estructura. Comenzar谩 con la ruta del directorio a nuestro archivo de c贸digo fuente. Luego, entre corchetes, indicar谩 el n煤mero de l铆nea de ese archivo al que apunta PDB, que en nuestro caso es “(3)”. La siguiente l铆nea, que comienza con el s铆mbolo “->”, indica la l铆nea a la que se apunta actualmente.

    Para cerrar el indicador de PDB, simplemente ingrese quit o exit en el indicador de PDB.

    Algunas otras cosas a tener en cuenta, si su programa acepta par谩metros como entradas, tambi茅n puede pasarlos a trav茅s de la l铆nea de comandos. Por ejemplo, si nuestro programa anterior hubiera requerido tres entradas del usuario, entonces este es el aspecto que tendr铆a nuestro comando:

    $ python -m pdb calc.py var1 var2 var3
    

    Continuando, si antes hab铆a cerrado el indicador de PDB a trav茅s del quit o exit comando, luego vuelva a ejecutar el archivo de c贸digo a trav茅s de PDB. Despu茅s de eso, ejecute el siguiente comando en el indicador de PDB:

    (Pdb) list
    

    La salida se ve as铆:

      1     # Filename: calc.py
      2
      3  -> operators = ['+', '-', '*', "https://Pharos.sh.com/"]
      4     numbers = [10, 20]
      5
      6     def calculator():
      7         print("Operators available: ")
      8         for op in operators:
      9             print(op)
     10
     11         print("Numbers to be used: ")
    (Pdb)
    

    Esto le mostrar谩 las primeras 11 l铆neas de su programa, con el “->” apuntando hacia la l铆nea actual que est谩 siendo ejecutada por el depurador. A continuaci贸n, intente este comando en el indicador de PDB:

    (Pdb) list 4,6
    

    Este comando debe mostrar solo las l铆neas seleccionadas, que en este caso son las l铆neas 4 a 6. Aqu铆 est谩 el resultado:

      4     numbers = [10, 20]
      5
      6     def calculator():
    (Pdb)
    

    Depurar con puntos de interrupci贸n

    La siguiente cosa importante que aprenderemos es el punto de ruptura. Los puntos de interrupci贸n se usan generalmente para programas m谩s grandes, pero para comprenderlos mejor veremos c贸mo funcionan en nuestro ejemplo b谩sico. Los puntos de ruptura son ubicaciones espec铆ficas que declaramos en nuestro c贸digo. Nuestro c贸digo se ejecuta hasta esa ubicaci贸n y luego se detiene. PDB asigna n煤meros autom谩ticamente a estos puntos.

    Tenemos las siguientes opciones diferentes para crear puntos de ruptura:

    • Por n煤mero de l铆nea
    • Por declaraci贸n de funci贸n
    • Por una condici贸n

    Para declarar un punto de interrupci贸n por n煤mero de l铆nea, ejecute el siguiente comando en el indicador de PDB:

    (Pdb) break calc.py:8
    

    Este comando inserta un punto de interrupci贸n en la octava l铆nea de c贸digo, que pausar谩 el programa una vez que llegue a ese punto. La salida de este comando se muestra como:

    Breakpoint 1 at /Users/junaid/Desktop/calc.py: 8
    (Pdb)
    

    Para declarar puntos de interrupci贸n en una funci贸n, ejecute el siguiente comando en el indicador de PDB:

    (Pdb) break calc.calculator
    

    Para insertar un punto de interrupci贸n de esta manera, debe declararlo usando el nombre del archivo y luego el nombre de la funci贸n. Esto da como resultado lo siguiente:

    Breakpoint 2 at /Users/junaid/Desktop/calc.py:6
    

    Como puede ver, a este punto de interrupci贸n se le ha asignado el n煤mero 2 autom谩ticamente, y tambi茅n se muestra el n煤mero de l铆nea, es decir, 6 en el que se declara la funci贸n.

    Los puntos de interrupci贸n tambi茅n se pueden declarar mediante una condici贸n. En ese caso, el programa se ejecutar谩 hasta que la condici贸n sea falsa y se detendr谩 cuando esa condici贸n se vuelva verdadera. Ejecute el siguiente comando en el indicador de PDB:

    (Pdb) break calc.py:8, op == "*"
    

    Esto rastrear谩 el valor de la op variable durante la ejecuci贸n y solo se rompe cuando su valor es “*” en la l铆nea 8.

    Para ver todos los puntos de ruptura que hemos declarado en forma de lista, ejecute el siguiente comando en el indicador de PDB:

    (Pdb) break
    

    La salida se ve as铆:

    Num Type         Disp Enb   Where
    1   breakpoint   keep yes   at /Users/junaid/Desktop/calc.py: 8
    2   breakpoint   keep yes   at /Users/junaid/Desktop/calc.py: 6
        breakpoint already hit 1 time
    3   breakpoint   keep yes   at /Users/junaid/Desktop/calc.py: 8
        stop only if op == "*"
    (Pdb)
    

    Por 煤ltimo, veamos c贸mo podemos deshabilitar, habilitar y borrar un punto de interrupci贸n espec铆fico en cualquier instancia. Ejecute el siguiente comando en el indicador de PDB:

    (Pdb) disable 2
    

    Esto desactivar谩 el punto de interrupci贸n 2, pero no lo eliminar谩 de nuestra instancia del depurador.

    En la salida ver谩 el n煤mero del punto de interrupci贸n desactivado.

    Disabled breakpoint 2 at /Users/junaid/Desktop/calc.py:6
    (Pdb)
    

    Imprimamos la lista de todos los puntos de interrupci贸n nuevamente para ver el valor “Enb” para el punto de interrupci贸n 2:

    (Pdb) break
    

    Salida:

    Num Type         Disp Enb   Where
    1   breakpoint   keep yes   at /Users/junaid/Desktop/calc.py:8
    2   breakpoint   keep no    at /Users/junaid/Desktop/calc.py:4 # you can see here that the "ENB" column for #2 shows "no"
        breakpoint already hit 1 time
    3   breakpoint   keep yes   at /Users/junaid/Desktop/calc.py:8
        stop only if op == "*"
    (Pdb)
    

    Para volver a habilitar el punto de interrupci贸n 2, ejecute el siguiente comando:

    (Pdb) enable 2
    

    Y nuevamente, aqu铆 est谩 el resultado:

    Enabled breakpoint 2 at /Users/junaid/Desktop/calc.py:6
    

    Ahora, si imprime la lista de todos los puntos de interrupci贸n nuevamente, el valor de la columna “Enb” para el punto de interrupci贸n 2 deber铆a mostrar un “s铆” nuevamente.

    Ahora borremos el punto de interrupci贸n 1, que lo eliminar谩 todo junto.

    (Pdb) clear 1
    

    El resultado es el siguiente:

    Deleted breakpoint 1 at /Users/junaid/Desktop/calc.py:8
    (Pdb)
    

    Si volvemos a imprimir la lista de puntos de interrupci贸n, ahora solo deber铆a mostrar dos filas de puntos de interrupci贸n. Veamos la salida del comando “romper”:

    Num Type         Disp Enb   Where
    2   breakpoint   keep yes   at /Users/junaid/Desktop/calc.py:4
        breakpoint already hit 1 time
    3   breakpoint   keep yes   at /Users/junaid/Desktop/calc.py:8
        stop only if op == "*"
    

    Exactamente lo que esper谩bamos.

    Antes de continuar con esta secci贸n, quiero mostrarle todo lo que se muestra cuando ejecutamos el c贸digo hasta el punto de interrupci贸n especificado. Para hacer eso, borremos todos los puntos de interrupci贸n anteriores y declaremos otro punto de interrupci贸n a trav茅s del indicador de PDB:

    1. Borrar todos los puntos de interrupci贸n

    (Pdb) clear
    

    Despu茅s de eso, escriba “y” y presione “Enter”. Deber铆a ver aparecer una salida como esta:

    Deleted breakpoint 2 at /Users/junaid/Desktop/calc.py:6
    Deleted breakpoint 3 at /Users/junaid/Desktop/calc.py:8
    

    2. Declare un nuevo punto de interrupci贸n

    Lo que deseamos lograr es que el c贸digo se ejecute hasta el punto en que el valor de num variable es mayor que 10. B谩sicamente, el programa deber铆a hacer una pausa antes de que se imprima el n煤mero “20”.

    (Pdb) break calc.py:13, num > 10
    

    3. Ejecute el c贸digo hasta este punto de interrupci贸n

    Para ejecutar el c贸digo, use el comando “continuar”, que ejecutar谩 el c贸digo hasta que llegue a un punto de interrupci贸n o finalice:

    (Pdb) continue
    

    Deber铆a ver el siguiente resultado:

    Operators available:
    +
    -
    *
    /
    Numbers to be used:
    10
    > /Users/junaid/Desktop/calc.py(13)calculator()
    -> print(num)
    

    Esto es exactamente lo que esper谩bamos, el programa se ejecuta hasta ese punto y luego se detiene, ahora depende de nosotros si deseamos cambiar algo, inspeccionar las variables o si queremos ejecutar el script hasta su finalizaci贸n. Para indicarle que se ejecute hasta su finalizaci贸n, vuelva a ejecutar el comando “continuar”. La salida debe ser la siguiente:

    20
    The program finished and will be restarted
    > /Users/junaid/Desktop/calc.py(3)<module>()
    -> operators = [ '+', '-', '*', "https://Pharos.sh.com/" ]
    

    En la salida anterior, se puede ver que el programa contin煤a exactamente desde donde lo dej贸, ejecuta la parte restante y luego se reinicia para permitirnos depurarlo m谩s si lo deseamos. Pasemos a la siguiente secci贸n ahora.

    Nota IMPORTANTE: Antes de seguir adelante, borre todos los puntos de interrupci贸n ejecutando el comando “borrar”, seguido de escribir “y” en el indicador de PDB.

    Funciones de paso y siguiente

    Por 煤ltimo, pero no menos importante, estudiemos el next y step funciones; estos se usar谩n con mucha frecuencia cuando comience a depurar sus aplicaciones, as铆 que aprendamos qu茅 hacen y c贸mo se pueden implementar.

    los step y next las funciones se utilizan para iterar a lo largo de nuestro c贸digo l铆nea por l铆nea; hay una peque帽a diferencia entre los dos. Mientras itera, si el step funci贸n encuentra una llamada de funci贸n, se mover谩 a la primera l铆nea de la definici贸n de esa funci贸n y nos mostrar谩 exactamente lo que est谩 sucediendo dentro de la funci贸n; mientras que, si el next funci贸n encuentra una llamada de funci贸n, ejecutar谩 todas las l铆neas de esa funci贸n de una sola vez y se detendr谩 en la siguiente llamada de funci贸n.

    驴Confuso? Veamos eso en un ejemplo.

    Vuelva a ejecutar el programa a trav茅s del indicador de PDB con el siguiente comando:

    $ python -m pdb calc.py
    

    Ahora escribe continue en el indicador de PDB y contin煤e haci茅ndolo hasta que el programa llegue al final. A continuaci贸n, mostrar茅 una secci贸n de toda la secuencia de entrada y salida, que es suficiente para explicar el punto. La secuencia completa es bastante larga y solo lo confundir铆a m谩s, por lo que se omitir谩.

    > /Users/junaid/Desktop/calc.py(1)<module>()
    -> operators = [ '+', '-', '*', "https://Pharos.sh.com/" ]
    (Pdb) step
    > /Users/junaid/Desktop/calc.py(2)<module>()
    -> numbers = [ 10, 20 ]
    .
    .
    .
    .
    > /Users/junaid/Desktop/calc.py(6)calculator()
    -> print("Operators available: " )
    (Pdb) step
    Operators available:
    > /Users/junaid/Desktop/calc.py(8)calculator()
    -> for op in operators:
    (Pdb) step
    > /Users/junaid/Desktop/calc.py(10)calculator()
    -> print(op)
    (Pdb) step
    +
    > /Users/junaid/Desktop/calc.py(8)calculator()
    -> for op in operators:
    (Pdb) step
    > /Users/junaid/Desktop/calc.py(10)calculator()
    -> print(op)
    
    .
    .
    .
    .
    

    Ahora, vuelva a ejecutar todo el programa, pero esta vez, use el comando “siguiente” en lugar de “paso”. Tambi茅n he mostrado el seguimiento de entrada y salida para eso.

    > /Users/junaid/Desktop/calc.py(3)<module>()
    -> operators = ['+', '-', '*', "https://Pharos.sh.com/"]
    (Pdb) next
    > /Users/junaid/Desktop/calc.py(4)<module>()
    -> numbers = [10, 20]
    (Pdb) next
    > /Users/junaid/Desktop/calc.py(6)<module>()
    -> def calculator():
    (Pdb) next
    > /Users/junaid/Desktop/calc.py(15)<module>()
    -> def main():
    (Pdb) next
    > /Users/junaid/Desktop/calc.py(18)<module>()
    -> main()
    (Pdb) next
    Operators available:
    +
    -
    *
    /
    Numbers to be used:
    10
    20
    --Return--
    

    Muy bien, ahora que tenemos el seguimiento de salida para ambas funciones, veamos en qu茅 se diferencian. Para el step funci贸n, puede ver que cuando el calculator se llama a la funci贸n, se mueve dentro de esa funci贸n y la recorre en “pasos”, mostr谩ndonos exactamente lo que est谩 sucediendo en cada paso.

    Sin embargo, si ve el seguimiento de salida del next funci贸n, cuando se llama a la funci贸n “principal”, no nos muestra lo que sucede dentro de esa funci贸n (es decir, una llamada posterior a la funci贸n de calculadora), y luego imprime directamente el resultado final en un solo paso / paso.

    Estos comandos son 煤tiles si est谩 iterando a trav茅s de un programa y desea recorrer ciertas funciones, pero no otras, en cuyo caso puede utilizar cada comando para sus prop贸sitos.

    Conclusi贸n

    En este tutorial, aprendimos sobre una t茅cnica sofisticada para depurar aplicaciones de Python utilizando un m贸dulo incorporado llamado PDB. Nos sumergimos en los diferentes comandos de resoluci贸n de problemas que nos proporciona PDB, incluido el next y step declaraciones, puntos de interrupci贸n, etc. Tambi茅n los aplicamos a un programa b谩sico para verlos en acci贸n.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *