¿Cómo recorrer el código de Python para ayudar a solucionar problemas?

186

En Java / C # puede pasar fácilmente por el código para rastrear lo que podría estar yendo mal, y los IDE hacen que este proceso sea muy fácil de usar.

¿Puedes rastrear el código de Python de manera similar?

Blankman
fuente

Respuestas:

264

¡Si! ¡Hay un depurador de Python llamado pdbsolo por hacer eso!

Puede iniciar un programa Python pdbmediante pdb myscript.pyo python -m pdb myscript.py.

Hay algunos comandos que puede emitir, que están documentados en la pdbpágina.

Algunos útiles para recordar son:

  • b: establecer un punto de interrupción
  • c: continúe depurando hasta llegar a un punto de interrupción
  • s: paso por el código
  • n: para ir a la siguiente línea de código
  • l: lista el código fuente del archivo actual (predeterminado: 11 líneas, incluida la línea que se está ejecutando)
  • u: navegar por un marco de pila
  • d: navegar por un marco de pila
  • p: para imprimir el valor de una expresión en el contexto actual

Si no desea utilizar un depurador de línea de comandos, algunos IDE como Pydev , Wing IDE o PyCharm tienen un depurador de GUI. Wing y PyCharm son productos comerciales, pero Wing tiene una edición "Personal" gratuita, y PyCharm tiene una edición comunitaria gratuita.

mit
fuente
10
Wow, no puedo creer que me esté costando encontrar un pdb gráfico para linux / ubuntu. ¿Me estoy perdiendo de algo? Puede que tenga que buscar hacer un complemento de SublimeText para ello.
ThorSummoner
44
PyCharm es bastante bueno como depurador gráfico, ¡y su Community Edition es gratis!
Pieter
@ThorSummoner, pudbes genial para eso. Tambiénpydev
alpha_989
pdbNo es una herramienta de línea de comandos. Para usarlo, use python -m pdb your_script.py.
jdhao
@jdhao Supongo que no es estándar, pero en Ubuntu el pdbcomando es parte del pythonpaquete. En cualquier caso, también se python -m <module>está convirtiendo en el estándar para otras cosas pip, por lo que probablemente sea mejor usarlo de forma predeterminada.
wjandrea
55

Al usar el depurador interactivo de Python 'pdb'

El primer paso es hacer que el intérprete de Python ingrese al modo de depuración.

A. Desde la línea de comando

La forma más directa, desde la línea de comandos, del intérprete de Python

$ python -m pdb scriptName.py
> .../pdb_script.py(7)<module>()
-> """
(Pdb)

B. Dentro del intérprete

Al desarrollar versiones tempranas de módulos y experimentarlo más iterativamente.

$ python
Python 2.7 (r27:82508, Jul  3 2010, 21:12:11)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pdb_script
>>> import pdb
>>> pdb.run('pdb_script.MyObj(5).go()')
> <string>(1)<module>()
(Pdb)

C. Desde dentro de su programa

Para un gran proyecto y un módulo de larga ejecución, puede iniciar la depuración desde el interior del programa utilizando import pdb y set_trace () de esta manera:

#!/usr/bin/env python
# encoding: utf-8
#

import pdb

class MyObj(object):
    count = 5
    def __init__(self):
        self.count= 9

    def go(self):
        for i in range(self.count):
            pdb.set_trace()
            print i
        return

if __name__ == '__main__':
    MyObj(5).go()

Depuración paso a paso para entrar en más interna

  1. Ejecute la siguiente declaración ... con "n" (siguiente)

  2. Repetir el último comando de depuración ... con ENTER

  3. Dejarlo todo ... con "q" (salir)

  4. Imprimir el valor de las variables ... con "p" (imprimir)

    a) pa

  5. Desactivar el indicador (Pdb) ... con "c" (continuar)

  6. Ver dónde estás ... con "l" (lista)

  7. Entrar en subrutinas ... con "s" (entrar)

  8. Continuando ... pero justo hasta el final de la subrutina actual ... con "r" (retorno)

  9. Asignar un nuevo valor

    a) ! b = "B"

  10. Establecer un punto de interrupción

    a) romper el número de lino

    b) nombre de función de interrupción

    c) romper el nombre del archivo: número de lino

  11. Punto de interrupción temporal

    a) romper el número de lino

  12. Punto de corte condicional

    a) romper el número de lino, condición

Nota: ** Todos estos comandos deben ejecutarse desde ** pdb

Para un conocimiento profundo, consulte: -

https://pymotw.com/2/pdb/

https://pythonconquerstheuniverse.wordpress.com/2009/09/10/debugging-in-python/

akD
fuente
41

Hay un módulo llamado 'pdb' en python. En la parte superior de tu script de Python, lo haces

import pdb
pdb.set_trace()

y entrará en modo de depuración. Puede usar 's' para avanzar, 'n' para seguir la siguiente línea similar a lo que haría con el depurador 'gdb'.

Senthil Kumaran
fuente
21

A partir de Python 3.7, puede usar la breakpoint()función incorporada para ingresar al depurador:

foo()
breakpoint()  # drop into the debugger at this point
bar()

Por defecto, breakpoint()importará pdby llamará pdb.set_trace(). Sin embargo, puede controlar el comportamiento de depuración mediante el sys.breakpointhook()uso de la variable de entorno PYTHONBREAKPOINT.

Ver PEP 553 para más información.

Eugene Yarmash
fuente
2
Cuando vi breakpointque estaba emocionado. Pero luego aprendí que es esencialmente un atajo import pdb; pdb.set_trace()y eso me entristeció. Desarrolladores de Python: concéntrese en mejorar PDB con características básicas de GDB como líneas de contexto, historial de comandos persistente y finalización automática de pestañas :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
11

ipdb (depurador de IPython)

ipdb agrega la funcionalidad IPython a pdb, ofreciendo las siguientes ENORMES mejoras:

  • finalización de pestaña
  • mostrar más líneas de contexto
  • resaltado de sintaxis

Al igual que pdg, ipdb todavía está lejos de ser perfecto y completamente rudimentario en comparación con GDB, pero ya es una gran mejora con respecto a pdb.

El uso es análogo pdb, simplemente instálelo con:

python3 -m pip install --user ipdb

y luego agregue a la línea desde la que desea depurar:

__import__('ipdb').set_trace(context=21)

Es probable que desee agregar un acceso directo para eso desde su editor, por ejemplo, para Vim snipmate tengo:

snippet ipd
    __import__('ipdb').set_trace(context=21)

así que puedo escribir solo ipd<tab>y se expande hasta el punto de interrupción. Luego, eliminarlo es fácil ddya que todo está contenido en una sola línea.

context=21aumenta el número de líneas de contexto como se explica en: ¿Cómo puedo hacer que ipdb muestre más líneas de contexto durante la depuración?

Alternativamente, también puede depurar programas desde el principio con:

ipdb3 main.py

pero generalmente no quieres hacer eso porque:

  • tendrías que revisar todas las definiciones de funciones y clases mientras Python lee esas líneas
  • No sé cómo configurar el tamaño del contexto allí sin hackear ipdb. Parche para permitirlo: https://github.com/gotcha/ipdb/pull/155

O, como alternativa, como en el pdb 3.2+ en bruto, puede establecer algunos puntos de interrupción desde la línea de comandos:

ipdb3 -c 'b 12' -c 'b myfunc' ~/test/a.py

aunque -c cestá roto por alguna razón: https://github.com/gotcha/ipdb/issues/156

python -m moduleSe ha solicitado la depuración en: ¿Cómo depurar un módulo Python ejecutado con python -m desde la línea de comandos? y desde Python 3.7 se puede hacer con:

python -m pdb -m my_module

Serias características faltantes de pdb e ipdb en comparación con GDB:

molestias específicas de ipdb:

Probado en Ubuntu 16.04, ipdb == 0.11, Python 3.5.2.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
5

Existe un breakpoint()método hoy en día, que reemplaza import pdb; pdb.set_trace().

También tiene varias características nuevas , como posibles variables de entorno.

johnnyheineken
fuente
3

Si vienes de Java / C # de fondo, supongo que tu mejor opción sería usar Eclipse con Pydev . Esto le proporciona un IDE completamente funcional con depurador incorporado. Lo uso también con django.

Liorsion
fuente
2

Python Tutor es un depurador en línea de un solo paso destinado a principiantes. Puede poner el código en la página de edición y luego hacer clic en "Visualizar ejecución" para iniciar su ejecución.

Entre otras cosas, admite:

Sin embargo, tampoco es compatible con muchas cosas , por ejemplo:

  • Lectura / escritura de archivos - use io.StringIOy en su io.BytesIOlugar: demo
  • Código que es demasiado grande, se ejecuta demasiado o define demasiadas variables u objetos
  • Argumentos de línea de comando
  • Muchos módulos de biblioteca estándar como argparse, csv, enum, html, os, struct, weakref ...
wjandrea
fuente
1

También es posible avanzar y rastrear mediante programación el código de Python (¡y es fácil!). Mire la documentación de sys.settrace () para más detalles. También aquí hay un tutorial para comenzar.

Autodidacta
fuente
1

PyCharm es un IDE para Python que incluye un depurador. Mire este video de YouTube para obtener una introducción sobre el uso del depurador de PyCharm para recorrer el código.

Tutorial de PyCharm: depure el código de Python con PyCharm

Nota: Esto no pretende ser un endoso o revisión. PyCharm es un producto comercial que hay que pagar, pero la compañía proporciona una licencia gratuita a estudiantes y profesores, así como una versión comunitaria "ligera" que es gratuita y de código abierto.

Captura de pantalla

jim
fuente