2011-12-15 23 views
10

¿Hay un pdb equivalente a disp en gdb?Python pdb (debugger) disp equivalente?

E.g. cuando estoy de depuración C usando GDB puedo tener variables impresos en cada 'paso' a través del código escribiendo:

disp var 

Cuando estoy usando Python depurar pdb me gustaría una funcionalidad similar, pero no parece disp Para estar allí, la documentación python pdb no parece ofrecer una alternativa, pero parece una omisión extraña.

+0

quizá IPDB tiene algunas funciones alternativa – bph

+0

Como alternativa, si te gusta una buena interfaz de usuario, es posible que desee utilizar [ pudb] (https://pypi.python.org/pypi/pudb). –

Respuesta

1

Durante la depuración de pdb, puede escribir el código python normal, más allá de los comandos de una letra, por lo que solo debe usar print var.

+0

¿quiere decir que pdb reimprimiría 'var' automáticamente cada vez que presione' s' o 'n' entonces? No estoy seguro de que así sea, parece lo mismo que escribir 'p var' para mí. La pregunta no es sobre cómo imprimir una variable usando el depurador, más acerca de cómo puedo usar pdb de manera más eficiente/efectiva ... – bph

+0

Lo siento, no, esto solo imprime la variable una vez. – jsbueno

+0

ok - mi nueva respuesta debería hacerlo. – jsbueno

3

El código de abajo usa las características de introspección de Python para agregar dos nuevos comandos al módulo PDB 0 simplemente ponga la función dada, y su llamada en un módulo separado, e importe este módulo antes de comenzar la depuración - usted debe tener el 'disp Los comandos 'y' undisp 'agregan y retractan relojes a las variables.

Funciona al parchear el módulo pdb de Python, que está escrito en python puro.

# -*- coding: utf-8 -*- 

def patch_pdb(): 
    import pdb 

    def wrap(func): 
     def new_postcmd(self, *args, **kw): 
      result = func(self, *args, **kw) 
      if hasattr(self, "curframe") and self.curframe and hasattr(self, "watch_list"): 
       for arg in self.watch_list: 
        try: 
         print >> self.stdout, "%s: %s"% (arg, self._getval(arg)) + ", ", 
        except: 
         pass 
       self.stdout.write("\n") 
      return result #func(self, *args, **kw) 

     return new_postcmd 

    pdb.Pdb.postcmd = wrap(pdb.Pdb.postcmd) 

    def do_disp(self, arg): 
     if not hasattr(self, "watch_list"): 
      self.watch_list = [] 
     self.watch_list.append(arg) 

    pdb.Pdb.do_disp = do_disp 

    def do_undisp(self, arg): 
     if hasattr(self, "watch_list"): 
      try: 
       self.watch_list.remove(arg) 
      except: 
       pass 

    pdb.Pdb.do_undisp = do_undisp 

patch_pdb() 

if __name__ == "__main__": 
    # for testing 
    import pdb; pdb.set_trace() 
    a = 0 
    for i in range(10): 
     print i 
     a += 2 

Por desgracia, sólo podría hacerlo visualizar el estado de las variables ya que donde previamente a la ejecución del último comando. (Lo intenté un poco, pero parchar en monopatín el módulo bdb, que es la base para el Pdb, no parecía funcionar tan bien). Puede intentar y cambiar los métodos en pdb.Pdb, bdb.Bdb o cmd.Cmd que están decorados por wrap para encontrar uno que se llame después de que haya cambiado el estado del marco depurado.

3

Puede configurar algunos alias que va a hacer esto para usted:

alias n next;; p var 
alias s step;; p var 

Impresión de toda una lista de nombres de variables se deja como ejercicio para el lector. Desafortunadamente hacerlo de esta manera significa que cuando envía el depurador una línea vacía, el "último comando" que ejecuta es p var en lugar de, por ejemplo, n. Si desea fijar que, a continuación, puede utilizar este conjunto un poco hacky del APP comandos en su lugar:

!global __stack; from inspect import stack as __stack 
!global __Pdb; from pdb import Pdb as __Pdb 
!global __pdb; __pdb = [__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self") for __framerec in __stack() if (__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self")).__class__ == __Pdb][-1] 

alias s step;; p var;; !__pdb.lastcmd = "!__pdb.cmdqueue.append('s')" 
alias n next;; p var;; !__pdb.lastcmd = "!__pdb.cmdqueue.append('n')"