Consejos de depuración de Python [cerrado]

164

¿Cuáles son tus mejores consejos para depurar Python?

No solo enumere un depurador en particular sin decir lo que realmente puede hacer.

Relacionado

desconocido
fuente

Respuestas:

139

PDB

Puede usar el módulo pdb, insertarlo en pdb.set_trace()cualquier lugar y funcionará como un punto de interrupción.

>>> import pdb
>>> a="a string"
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) p a
'a string'
(Pdb)

Para continuar la ejecución use c(o conto continue).

Es posible ejecutar expresiones arbitrarias de Python usando pdb. Por ejemplo, si encuentra un error, puede corregir el código y luego escribir una expresión de tipo para tener el mismo efecto en el código en ejecución

ipdb es una versión de pdb para IPython . Permite el uso de pdb con todas las características de IPython, incluida la finalización de pestañas.

También es posible configurar pdb para que se ejecute automáticamente en una excepción no detectada.

Pydb fue escrito para ser una versión mejorada de Pdb. Beneficios?

ghostdog74
fuente
Aquí hay un artículo sobre el uso de pdb: sontek.net/debugging-python-with-pdb
sontek
Personalmente, me gusta más ipdb .
Sardathrion - contra el abuso SE
1
Aparentemente hay una reescritura de pydb llamada pydbgr
Ehtesh Choudhury
SublimeText tiene un gran complemento para agregar puntos de interrupción de Python al código: sublime.wbond.net/packages/Python%20Breakpoints
Dennis Golomazov
Si está desarrollando una aplicación web, agregue una vista myserver.com/pdben modo de depuración que simplemente lo haga import pdb; pdb.set_trace(). Si está utilizando Flask / Werkzeug que tiene un depurador interactivo, también puede tener una vista que simplemente lo haga assert False.
osa
78

http://pypi.python.org/pypi/pudb , un depurador de Python basado en consola y pantalla completa.

Su objetivo es proporcionar todas las sutilezas de los depuradores modernos basados ​​en GUI en un paquete más ligero y compatible con el teclado. PuDB le permite depurar el código justo donde lo escribe y probarlo, en un terminal. Si ha trabajado con las excelentes (pero hoy en día antiguas) herramientas Turbo Pascal o C basadas en DOS, la interfaz de usuario de PuDB puede parecerle familiar.

captura de pantalla de pudb

Agradable para depurar scripts independientes, solo ejecuta

python -m pudb.run my-script.py
miku
fuente
Instalar conpip install pudb
congusbongus
40

Si está utilizando pdb, puede definir alias para accesos directos. Yo uso estos:

# Ned's .pdbrc

# Print a dictionary, sorted. %1 is the dict, %2 is the prefix for the names.
alias p_ for k in sorted(%1.keys()): print "%s%-15s= %-80.80s" % ("%2",k,repr(%1[k]))

# Print the instance variables of a thing.
alias pi p_ %1.__dict__ %1.

# Print the instance variables of self.
alias ps pi self

# Print the locals.
alias pl p_ locals() local:

# Next and list, and step and list.
alias nl n;;l
alias sl s;;l

# Short cuts for walking up and down the stack
alias uu u;;u
alias uuu u;;u;;u
alias uuuu u;;u;;u;;u
alias uuuuu u;;u;;u;;u;;u
alias dd d;;d
alias ddd d;;d;;d
alias dddd d;;d;;d;;d
alias ddddd d;;d;;d;;d;;d
Ned Batchelder
fuente
¿Cómo define usted este alias?
Casebash
9
Ponga esto en ~ / .pdbrc
Ned Batchelder
en Windows puedes ponerlo en ~ / _ipython / ipythonrc.ini
fastmultiplication
33

Inicio sesión

Python ya tiene un excelente módulo de registro incorporado . Es posible que desee utilizar la plantilla de registro aquí .

El módulo de registro le permite especificar un nivel de importancia; durante la depuración puede registrar todo, mientras que durante la operación normal solo puede registrar cosas críticas. Puedes encender y apagar las cosas.

La mayoría de las personas solo usan declaraciones de impresión básicas para depurar y luego eliminan las declaraciones de impresión. Es mejor dejarlos dentro, pero deshabilitarlos; luego, cuando tenga otro error, puede volver a habilitar todo y revisar sus registros.

Esta puede ser la mejor manera posible de depurar programas que necesitan hacer cosas rápidamente, como los programas de red que necesitan responder antes de que el otro extremo de la conexión de red agote el tiempo y desaparezca. Es posible que no tenga mucho tiempo para un depurador de un solo paso; pero puede dejar que su código se ejecute y registrar todo, luego examinar detenidamente los registros y descubrir qué está sucediendo realmente.

EDITAR: La URL original para las plantillas fue: http://aymanh.com/python-debugging-techniques

Falta esta página, así que la reemplacé con una referencia a la instantánea guardada en archive.org: http://web.archive.org/web/20120819135307/http://aymanh.com/python-debugging-techniques

En caso de que desaparezca nuevamente, aquí están las plantillas que mencioné. Este es un código tomado del blog; No lo escribi.

import logging
import optparse

LOGGING_LEVELS = {'critical': logging.CRITICAL,
                  'error': logging.ERROR,
                  'warning': logging.WARNING,
                  'info': logging.INFO,
                  'debug': logging.DEBUG}

def main():
  parser = optparse.OptionParser()
  parser.add_option('-l', '--logging-level', help='Logging level')
  parser.add_option('-f', '--logging-file', help='Logging file name')
  (options, args) = parser.parse_args()
  logging_level = LOGGING_LEVELS.get(options.logging_level, logging.NOTSET)
  logging.basicConfig(level=logging_level, filename=options.logging_file,
                      format='%(asctime)s %(levelname)s: %(message)s',
                      datefmt='%Y-%m-%d %H:%M:%S')

  # Your program goes here.
  # You can access command-line arguments using the args variable.

if __name__ == '__main__':
  main()

Y aquí está su explicación de cómo usar lo anterior. Nuevamente, no obtengo el crédito por esto:


Por defecto, el módulo de registro imprime mensajes críticos, de error y de advertencia. Para cambiar esto para que se impriman todos los niveles, use:

$ ./your-program.py --logging=debug

Para enviar mensajes de registro a un archivo llamado debug.log, use:

$ ./your-program.py --logging-level=debug --logging-file=debug.log

steveha
fuente
1
El problema con el módulo de registro es que rompe en gran medida con Unicode y se necesitan varias soluciones para que funcione en aplicaciones internacionalizadas. Sin embargo, esta sigue siendo la mejor solución de registro para Python.
Jacek Konieczny
El enlace "plantilla de registro aquí" está muerto. Por favor actualice.
Yohann
20

Es posible imprimir qué líneas de Python se ejecutan (¡gracias Geo!). Esto tiene cualquier número de aplicaciones, por ejemplo, puede modificarlo para verificar cuándo se llaman funciones particulares o agregar algo como ## para que solo rastree líneas particulares.

code.interact te lleva a una consola interactiva

import code; code.interact(local=locals())

Si desea poder acceder fácilmente al historial de su consola, consulte: " ¿Puedo tener un mecanismo de historial como en el shell? " (Tendrá que buscarlo).

El autocompletado puede habilitarse para el intérprete .

Casebash
fuente
19

ipdb es como pdb, con la genialidad de ipython.

Alex Gaynor
fuente
55
¿Podría agregar más detalles sobre lo que puede hacer?
Casebash el
17

print declaraciones

  • Algunas personas recomiendan una debug_printfunción en lugar de imprimir para deshabilitar fácilmente
  • El pprintmódulo es invaluable para estructuras complejas.
hasen j
fuente
3
+1 cuando falla cada depurador, print es tu amigo, sí debug_print sería una buena adición
Anurag Uniyal
Generalmente imprimo primero y luego depuro segundo, excepto cuando que podré resolver trazando una sección en particular
Casebash el
44
En realidad, el módulo de registro hace exactamente eso.
e-satis
Es cierto, pero se debe configurar el registro. Voy a aprender cómo utilizar el módulo después de honores
Casebash
print puede ser útil para casos simples y especialmente cuando se desarrollan proyectos con poco tiempo de inicio. Por otro lado, puede ser adictiva y usarla por PDB o cualquier otro depurador en escenarios más complejos por lo general causa dolores de cabeza
vinilios
16

La forma obvia de depurar un script

python -m pdb script.py
  • útil cuando ese script genera una excepción
  • útil cuando se usa virtualenv y el comando pdb no se ejecuta con la versión de venvs python.

si no sabes exactamente dónde está ese script

python -m pdb ``which <python-script-name>``
vinilios
fuente
15

PyDev

PyDev tiene un depurador interactivo bastante bueno. Tiene expresiones de observación, lista para evaluar, listas de subprocesos y pilas y (casi) todas las comodidades habituales que espera de un depurador visual moderno. Incluso puede adjuntar a un proceso en ejecución y realizar una depuración remota.

Sin embargo, al igual que otros depuradores visuales, me resulta útil principalmente para problemas simples o para problemas muy complicados después de haber intentado todo lo demás. Todavía hago la mayor parte del trabajo pesado con la tala.

itsadok
fuente
¿Tiene la capacidad de editar y continuar?
Casebash
@CaseBash no, pero esa característica está planeada. Incluso sin él, sin embargo, la velocidad y la facilidad de establecer puntos de interrupción / desarmado y mirando a través de valores de la variable sigue siendo muy útil
Jiaaro
12

Winpdb es muy agradable y, al contrario de su nombre, es completamente multiplataforma.

Tiene un depurador de GUI y basado en indicador muy agradable , y admite depuración remota.

orip
fuente
@Casebash - se agregaron más detalles
orip
1
+1 Este es el único depurador de python que he encontrado hasta ahora que puede manejar subprocesos múltiples.
Lee Netherton el
Tenga cuidado con su "manejo" de subprocesos múltiples: cualquier excepción en cualquier subproceso hace que todo el proceso se congele. No es malo si lo sabes, muy doloroso si no lo eres
Walt W
El proyecto parece muerto a partir de abril de 2014
Alojz Janez
7

En Vim, tengo estos tres enlaces:

map <F9> Oimport rpdb2; rpdb2.start_embedded_debugger("asdf") #BREAK<esc>
map <F8> Ofrom nose.tools import set_trace; set_trace() #BREAK<esc>
map <F7> Oimport traceback, sys; traceback.print_exception(*sys.exc_info()) #TRACEBACK<esc>

rpdb2es un depurador de Python remoto, que se puede usar con WinPDB, un depurador gráfico sólido. Porque sé que preguntarás, puede hacer todo lo que espero que haga un depurador gráfico :)

Utilizo pdbdesde nose.toolspara poder depurar las pruebas unitarias, así como el código normal.

Finalmente, el F7mapeo imprimirá un rastreo (similar al tipo que obtienes cuando una excepción aparece en la parte superior de la pila). Lo he encontrado realmente útil más de unas pocas veces.

David Wolever
fuente
4

Definiendo métodos repr () útiles para sus clases (para que pueda ver qué es un objeto) y utilizando el formato repr () o "% r"% (...) o "... {0! R} ..". (...) en sus mensajes / registros de depuración, en mi humilde opinión, es una clave para la depuración eficiente.

Además, los depuradores mencionados en otras respuestas harán uso de los métodos repr ().

Jacek Konieczny
fuente
2

Obtener un seguimiento de pila de una aplicación Python en ejecución

Hay varios trucos aquí . Éstos incluyen

  • Irrumpir en un intérprete / imprimir una traza de pila enviando una señal
  • Obtener un seguimiento de pila de un proceso de Python no preparado
  • Ejecutar el intérprete con banderas para que sea útil para la depuración
Casebash
fuente
2

Si no le gusta pasar tiempo en depuradores (y no aprecia la mala usabilidad de la pdbinterfaz de línea de comandos), puede volcar el seguimiento de ejecución y analizarlo más tarde. Por ejemplo:

python -m trace -t setup.py install > execution.log

Esto volcará toda la línea de setup.py installejecución de origen execution.log.

Para facilitar la personalización de la salida de rastreo y escribir sus propios trazadores, reuní algunas piezas de código en el módulo xtrace (dominio público).

anatoly techtonik
fuente
1

Cuando es posible, depuro usando M-x pdbemacs para la depuración a nivel fuente.

themis
fuente
1

Hay un curso completo en línea llamado " Depuración de software " por Andreas Zeller en Udacity, lleno de consejos sobre depuración:

Resumen del curso

En esta clase aprenderá cómo depurar programas sistemáticamente, cómo automatizar el proceso de depuración y construir varias herramientas de depuración automatizadas en Python.

¿Por qué tomar este curso?

Al final de este curso, tendrá una sólida comprensión sobre la depuración sistemática, sabrá cómo automatizar la depuración y habrá construido varias herramientas de depuración funcionales en Python.

Prerrequisitos y requisitos

Se requieren conocimientos básicos de programación y Python a nivel de Udacity CS101 o superior. La comprensión básica de la programación orientada a objetos es útil.

Muy recomendable.

Udi
fuente
0

si desea una buena forma gráfica de imprimir su pila de llamadas de manera legible, consulte esta utilidad: https://github.com/joerick/pyinstrument

Ejecutar desde la línea de comando:

python -m pyinstrument myscript.py [args...]

Ejecutar como un módulo:

from pyinstrument import Profiler

profiler = Profiler()
profiler.start()

# code you want to profile

profiler.stop()
print(profiler.output_text(unicode=True, color=True))

Corre con django:

Sólo tiene que añadir pyinstrument.middleware.ProfilerMiddlewarea MIDDLEWARE_CLASSES, a continuación, añadir ?profileal final de la URL de solicitud para activar el generador de perfiles.

Conejera
fuente