Cómo ejecutar declaraciones de varias líneas dentro del depurador (PDB) de Python

157

Así que estoy ejecutando un script de Python dentro del cual estoy llamando al depurador de Python, PDB escribiendo:

import ipdb; ipdb.set_trace()

(La versión de PDB de iPython, aunque no creo que marque la diferencia; lo uso solo para la salida en color).

Ahora, cuando llego al depurador, quiero ejecutar una instrucción de varias líneas, como una cláusula if o un bucle for, pero tan pronto como escribo

if condition:

y presiono la tecla de retorno, recibo el mensaje de error *** SyntaxError: invalid syntax (<stdin>, line 1)

¿Cómo se pueden ejecutar declaraciones de varias líneas dentro de PDB? Si no es posible, ¿hay alguna forma de evitar que se siga ejecutando una cláusula if o un bucle for?

Miguel
fuente

Respuestas:

265

Puede hacer esto mientras está en pdb para iniciar una sesión temporal interactiva de Python con todas las variables locales disponibles:

(pdb) !import code; code.interact(local=vars())
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

Cuando haya terminado, use Ctrl-D para volver al indicador pdb normal.

Simplemente no presione Ctrl-C, eso terminará toda la sesión pdb.

Marius Gedminas
fuente
46
Parece que la misma se puede lograr utilizando el AP interactde comandos ( como he aprendido de este mensaje de seguimiento de errores ).
gerrit
3
¿Por qué es !necesario en la importdeclaración?
Indradhanush Gupta
19
Probablemente no sea necesario, pero tengo la costumbre de prefijar todas las declaraciones de Python en pdb con !, para evitar accidentes. Por ejemplo, c = 42en pdb continuaría la ejecución en lugar de asignar a variable c.
Marius Gedminas
8
¡@MariusGedminas lo más frustrante con PDB! Sería bueno si sus comandos tuvieran que tener el prefijo ...
Ian Clark
Nota: Ctrl-D parece ser la forma correcta de salir interacttambién, pero no funciona bien con Spyder para mí.
Josiah Yoder
69

En python3 ipdb(y pdb) tenemos un comando llamado interactuar . Se puede usar para:

Inicie un intérprete interactivo (utilizando el módulo de código ) cuyo espacio de nombres global contiene todos los nombres (globales y locales) encontrados en el ámbito actual.

Para usarlo, simplemente ingrese interacten el indicador pdb. Entre otras cosas, es útil para aplicar código que abarca varias líneas y también para evitar la activación accidental de otros comandos pdb.

vaer-k
fuente
2
Me da "NameError: el nombre 'interactuar' no está definido" al hacer eso.
Jason
1
@jason versión 3.2 o superior
vaer-k
2
Eso explica. Estaba en Python 2.7.
Jason
Cuidado, esto en realidad arrojó un error que interactúa podría no está definido y salió del proceso
Camron_Godbout
1
Creo que sugerir evitar interactes una sugerencia demasiado fuerte. 90% esto es todo lo que necesito, y es mucho más fácil de escribir quefrom IPython import embed; embed()
vaer-k
43

Mi recomendación es usar la incrustación de IPython.

ipdb> from IPython import embed; embed()
fx-kirin
fuente
2
Si tiene un error de valor no definido en la comprensión de la lista, intente usarlo desde IPython import embed; embed(user_ns=locals()).
fx-kirin
1
Esto funciona mucho mejor para mí que la respuesta aceptada. Por ejemplo, permite la edición adecuada de multilínea, como retroceder algunas líneas y arreglar algo, para que no tenga que volver a escribir toda su expresión de varias líneas nuevamente ... Estoy pasando los locales como @ fx-kirin sugirió.
ZeDuS
33

Dentro del intérprete o depurador Python (2.7.1) (importar pdb), puede ejecutar una instrucción de varias líneas con la siguiente sintaxis.

for i in range(5): print("Hello"); print("World"); print(i)

Nota: Cuando estoy dentro del intérprete, tengo que presionar regresar dos veces antes de que se ejecute el código. Dentro del depurador, sin embargo, solo tengo que presionar return una vez.

Garrett Hyde
fuente
55
No permite ejecutar nada más profundo que un nivel.
Antony Hatchkins el
7

Existe el caso especial si desea que se ejecuten un par de comandos al alcanzar un punto de interrupción. Luego está el comando depurador commands. Le permite ingresar múltiples líneas de comandos y luego finalizar toda la secuencia con la endpalabra clave. Más con (pdb) help commands.

ThomasH
fuente
2

No sé si puede hacer esto, sin embargo, sería una gran característica para ipdb. Puede utilizar listas de comprensión, por supuesto, y ejecutar expresiones simples de varias líneas como:

if y == 3: print y; print y; print y;

También puede escribir algunas funciones de antemano para hacer lo que sea que necesite hacer que normalmente tomaría varias líneas.

zeekay
fuente
-6

Escriba su código en un editor de texto, luego péguelo en el depurador:

if True:
    print('a')

Es una solución tonta, pero también sucia rápida y de trabajo. Funciona en la terminal de Linux, pero no estoy seguro de si funcionará en la consola de Windows.

bizi
fuente
3
Honestamente, no diría que llamar a un programa externo, escribir, copiar y pegar es rápido , simplemente sucio: P
The Data Scientician
44
Esto, no funcionó para mí, y thew*** SyntaxError: unexpected EOF while parsing
Yash Kant