Jak wykonywać instrukcje wielowierszowe we własnym debugerze Pythona (PDB)


157

Więc uruchamiam skrypt w języku Python, w ramach którego wywołuję debugger języka Python, PDB, pisząc:

import ipdb; ipdb.set_trace()

(Wersja PDB iPythona, chociaż nie sądzę, żeby to miało znaczenie; używam go tylko do kolorowego wyjścia).

Teraz, kiedy dojdę do debugera, chcę wykonać instrukcję wielowierszową, taką jak klauzula if lub pętla for, ale gdy tylko wpiszę

if condition:

i naciskam klawisz powrotu, pojawia się komunikat o błędzie *** SyntaxError: invalid syntax (<stdin>, line 1)

Jak można wykonywać wielowierszowe instrukcje w PDB? Jeśli nie jest to możliwe, czy istnieje sposób na obejście tego, aby nadal wykonywać klauzulę if lub pętlę for?

Odpowiedzi:


265

Możesz to zrobić będąc w pdb, aby uruchomić tymczasową interaktywną sesję Pythona ze wszystkimi dostępnymi zmiennymi lokalnymi:

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

Kiedy skończysz, użyj Ctrl-D, aby powrócić do zwykłego monitu pdb.

Po prostu nie naciskaj Ctrl-C, to zakończy całą sesję pdb.


46
Wydaje się, że to samo można osiągnąć za pomocą interactpolecenia pdb ( jak dowiedziałem się z tego komunikatu śledzenia błędów ).
gerrit

3
Dlaczego jest to !potrzebne w importoświadczeniu?
Indradhanush Gupta

19
Prawdopodobnie nie jest to potrzebne, ale mam zwyczaj poprzedzać wszystkie instrukcje Pythona w pdb !, aby uniknąć wypadków. Np. c = 42W pdb kontynuowałoby wykonywanie zamiast przypisywania do zmiennej c.
Marius Gedminas

8
@MariusGedminas najbardziej frustrująca rzecz z PDB! Byłoby miło, gdyby ich polecenia musiały być poprzedzone ...
Ian Clark

Uwaga: Ctrl-D wydaje się być również właściwym sposobem na wyjście interact, ale dla mnie nie działa dobrze ze Spyderem.
Josiah Yoder

69

W python3 ipdb(i pdb) mamy polecenie o nazwie interact . Może służyć do:

Uruchom interaktywny interpreter (używając modułu kodu ), którego globalna przestrzeń nazw zawiera wszystkie (globalne i lokalne) nazwy znalezione w bieżącym zakresie.

Aby z niego skorzystać, po prostu wpisz interactw wierszu polecenia pdb. Jest to przydatne między innymi do stosowania kodu obejmującego wiele linii, a także do unikania przypadkowego wyzwalania innych poleceń pdb.


2
Kiedy to robię, otrzymuję komunikat „NameError: name 'interact' is not specified".
Jason,

1
@jason w wersji 3.2 lub nowszej
vaer-k

2
To wyjaśnia. Byłem w Pythonie 2.7.
Jason,

Ostrożnie, to faktycznie spowodowało błąd, że interakcja nie została zdefiniowana i zakończyła proces
Camron_Godbout

1
Myślę, że sugerowanie unikania interactjest zbyt mocną sugestią. 90% to wszystko, czego kiedykolwiek potrzebuję, a from IPython import embed; embed()
pisanie

43

Moją rekomendacją jest użycie osadzania IPython.

ipdb> from IPython import embed; embed()

2
Jeśli masz wartość nie jest zdefiniowana jako błąd w zrozumieniu listy, spróbuj użyć z IPython import embed; embed(user_ns=locals()).
fx-kirin

1
to działa dla mnie znacznie lepiej niż zaakceptowana odpowiedź. Na przykład - pozwala na poprawną edycję multilinii - jak cofnięcie się o kilka linii i naprawienie czegoś, żeby nie trzeba było ponownie przepisywać całego wyrażenia wieloliniowego ... przekazuję lokalne jako @ fx-kirin zasugerował.
ZeDuS

33

Wewnątrz interpretera lub debugera języka Python (2.7.1) (import pdb) można wykonać instrukcję wielowierszową o następującej składni.

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

Uwaga: kiedy jestem wewnątrz interpretera, muszę dwukrotnie nacisnąć klawisz Return, zanim kod zostanie wykonany. Jednak w debugerze muszę tylko raz nacisnąć klawisz powrotu.


5
Nie pozwala na prowadzenie niczego głębszego niż jeden poziom.
Antony Hatchkins,

7

Jest to specjalny przypadek, jeśli chcesz, aby kilka poleceń zostało wykonanych po uderzeniu w punkt przerwania. Następnie jest polecenie debugera commands. Umożliwia wprowadzenie wielu wierszy poleceń, a następnie zakończenie całej sekwencji endsłowem kluczowym. Więcej z (pdb) help commands.


2

Nie wiem, czy możesz to zrobić, ale to byłaby świetna funkcja dla ipdb. Możesz oczywiście używać list składanych i wykonywać proste wyrażenia wielowierszowe, takie jak:

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

Możesz również wcześniej napisać kilka funkcji, aby zrobić wszystko, co potrzebujesz, co normalnie zajmie wiele linii.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.