Come eseguire istruzioni multilinea all'interno del proprio debugger (PDB) di Python


157

Quindi sto eseguendo uno script Python all'interno del quale sto chiamando il debugger di Python, PDB scrivendo:

import ipdb; ipdb.set_trace()

(La versione di PDB di iPython, anche se per la verità non penso che faccia differenza; lo uso solo per l'output colorato).

Ora, quando arrivo al debugger, voglio eseguire un'istruzione multilinea come una clausola if o un ciclo for ma appena scrivo

if condition:

e premo il tasto Invio, ricevo il messaggio di errore *** SyntaxError: invalid syntax (<stdin>, line 1)

Come si possono eseguire istruzioni multilinea all'interno del PDB? Se non è possibile, c'è un modo per eseguire ancora una clausola if o un ciclo for?

Risposte:


265

Puoi farlo mentre sei in pdb per avviare una sessione Python interattiva temporanea con tutte le variabili locali disponibili:

(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)
>>> 

Al termine, utilizzare Ctrl-D per tornare al normale prompt pdb.

Basta non premere Ctrl-C, che terminerà l'intera sessione pdb.


46
Sembra che lo stesso si possa ottenere usando il interactcomando pdb ( come ho appreso da questo messaggio di tracciamento dei bug ).
Gerrit,

3
Perché è !necessario nella importdichiarazione?
Indradhanush Gupta,

19
Probabilmente non è necessario, ma ho l'abitudine di anteporre a tutte le istruzioni Python in pdb !per evitare incidenti. Ad esempio c = 42in pdb continuerebbe l' esecuzione invece di assegnare alla variabile c.
Marius Gedminas,

8
@MariusGedminas la cosa più frustrante con PDB! Sarebbe bello se i loro comandi dovessero essere prefissati ...
Ian Clark il

Nota: Ctrl-D sembra essere anche il modo giusto per uscire interact, ma per me non gioca bene con Spyder.
Josiah Yoder,

69

In python3 ipdb(e pdb) hanno un comando chiamato interagisci . Può essere usato per:

Avviare un interprete interattivo (utilizzando il modulo di codice ) il cui spazio dei nomi globale contiene tutti i nomi (globali e locali) trovati nell'ambito corrente.

Per usarlo, basta inserire interactal prompt pdb. Tra le altre cose, è utile per applicare il codice su più righe e anche per evitare l'attivazione accidentale di altri comandi pdb.


2
Mi dà "NameError: name 'interact' non è definito" quando lo faccio.
Jason il

1
@jason versione 3.2 o successiva
vaer-k

2
Questo spiega. Ero in Python 2.7.
Jason il

Attento, questo in realtà ha generato un errore che l'interazione non è stata definita ed è uscito dal processo
Camron_Godbout

1
Penso che suggerire di evitare interactsia un suggerimento troppo forte. 90% questo è tutto ciò di cui ho bisogno, ed è molto più facile da scrivere difrom IPython import embed; embed()
vaer-k

43

La mia raccomandazione è di usare l'incorporamento di IPython.

ipdb> from IPython import embed; embed()

2
Se stai riscontrando un valore non definito errore nella comprensione dell'elenco, prova a utilizzare da IPython import embed; embed(user_ns=locals()).
fx-kirin,

1
questo funziona molto meglio per me rispetto alla risposta accettata. Ad esempio - consente la corretta modifica di multilinea - come tornare indietro di alcune righe e correggere qualcosa, quindi non devi riscrivere di nuovo l'intera tua espressione multi-riga ... Sto passando la gente del posto come @ fx-kirin suggerito.
ZeDuS,

33

All'interno dell'interprete o debugger di Python (2.7.1) (import pdb), è possibile eseguire un'istruzione multilinea con la seguente sintassi.

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

Nota: quando mi trovo all'interno dell'interprete, devo premere Invio due volte prima che il codice venga eseguito. All'interno del debugger, tuttavia, devo solo premere Invio una volta.


5
Non consente di eseguire qualcosa di più profondo di un livello.
Antony Hatchkins,

7

C'è il caso speciale se si desidera eseguire un paio di comandi quando si colpisce un punto di interruzione. Quindi c'è il comando debugger commands. Ti permette di inserire più righe di comandi e quindi terminare l'intera sequenza con la endparola chiave. Più con (pdb) help commands.


2

Non so se puoi farlo, sarebbe comunque un'ottima funzionalità per ipdb. Puoi ovviamente usare la comprensione dell'elenco ed eseguire semplici espressioni multilinea come:

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

Potresti anche scrivere alcune funzioni in anticipo per fare qualunque cosa tu debba fare che normalmente richiederebbe più righe.


-6

Scrivi il tuo codice in un editor di testo, quindi incollalo nel debugger:

if True:
    print('a')

È una soluzione sciocca, ma anche sporca e veloce. Funziona su un terminale Linux, ma non sono sicuro che funzionerà su console Windows.


3
Onestamente, non direi che chiamare un programma esterno, scrivere, copiare e incollare sia veloce , sporco: P
The Data Scientician

4
Questo, non ha funzionato per me, e thew*** SyntaxError: unexpected EOF while parsing
Yash Kant il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.