¿Cómo ves una variable en pdb?

Estoy depurando una secuencia de comandos de python, y quiero ver una variable para un cambio (al igual que usted puede ver una dirección de memoria en gdb). ¿Hay alguna forma de hacer esto?

Esta es una manera realmente hacky de hacer esto con pdb . Estos comandos se pueden colocar en su ~/.pdbrc para que se carguen automáticamente cada vez que use pdb .

 !global __currentframe, __stack; from inspect import currentframe as __currentframe, stack as __stack !global __copy; from copy import copy as __copy !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 _setup_watchpoint !global __key, __dict, __val; __key = '%1'; __dict = __currentframe().f_locals if __currentframe().f_locals.has_key(__key) else __currentframe().f_globals; __val = __copy(%1) alias _nextwatch_internal next;; !if __dict[__key] == __val: __pdb.cmdqueue.append("_nextwatch_internal %1") alias _stepwatch_internal step;; !if __dict[__key] == __val: __pdb.cmdqueue.append("_stepwatch_internal %1") alias nextwatch __pdb.cmdqueue.extend(["_setup_watchpoint %1", "_nextwatch_internal"]) alias stepwatch __pdb.cmdqueue.extend(["_setup_watchpoint %1", "_stepwatch_internal"]) 

Esto agrega dos comandos, nextwatch y stepwatch cada uno de los cuales toma un nombre variable varname como argumento. Harán una copia superficial de la variable local del marco actual para varname si es posible, y continuarán ejecutando el next step o step respectivamente hasta que el nombre indique cambios.

Esto funciona en CPython 2.7.2 pero se basa en algunos internos de pdb por lo que probablemente se romperá en otros lugares.

Para observar una variable cuando está llegando a un punto de interrupción , puede usar el commands comandos. Ej. some_variable al alcanzar el punto de interrupción # 1 ( ejemplo canónico de pdb doc ).

 (Pdb) commands 1 (com) print some_variable (com) end (Pdb) 

Actualización para Python 3

 (Pdb) commands 1 (com) print(some_variable) (com) end (Pdb) 

Además, puede usar el comando de condition para asegurarse de que el punto de interrupción solo se scope cuando la variable tome un cierto valor.

p.ej:

 (Pdb) condition 1 some_variable==some_value 

Para Python 3 :

Puedes usar la funcionalidad de visualización de pdb.

Una vez que llegas al punto de interrupción simplemente escribe

ipdb> expresión de pantalla

ejemplo:

 ipdb> display instance display instance:  ipdb> display instance.id display instance.id: 9 ipdb> display instance.university display instance.university:  ipdb> display Currently displaying: instance.university:  instance.id: 9 instance:  ipdb> 

Como puede ver, cada vez que escribe display, se imprimirán todos sus relojes (expresiones). Puede usar la función incorporada no undisplay para eliminar ciertos relojes.

También puedes usar la expresión pp para imprimir la expresión (muy útil)

Una posible solución es usar pdb ++ :

 pip install pdbpp 

Luego “marque” el objeto que desea ver con el decorador @pdb.break_on_setattr :

 from pdb import break_on_setattr @break_on_setattr('bar') class Foo(object): pass f = Foo() f.bar = 42 # the program breaks here 

Aquí pdb se interrumpirá en cualquier cambio de la bar atributos en cualquier objeto Foo.

Advertencias
Solo las invocaciones del método __setattr__ subyacente activarán el punto de interrupción. Esto significa que f.bar = 'XYZ' y setattr(f, 'XYZ') funcionarán, pero manipular la bar -objeto no activará el punto de interrupción:

 f.bar = [] f.bar.append(7) # will NOT trigger breakpoint f.bar = 2 f.bar += 5 # will trigger breakpoint 

Nota: @break_on_setattr no es parte del estándar pdb -module. pdb se reemplaza / parchea por el pdbpp .

También puede envolver un objeto existente (a través de su clase) después de pdb.set_trace() :

 (Pdb++) import pdb (Pdb++) pdb.break_on_setattr('tree_id')(self.__class__) (Pdb++) continue