upuść do interpretera Pythona podczas wykonywania funkcji

90

Mam moduł Pythona z funkcją:

def do_stuff(param1 = 'a'):
    if type(param1) == int:
        # enter python interpreter here
        do_something()
    else:
        do_something_else()

czy jest sposób, aby wpaść do interpretera wiersza poleceń, w którym mam komentarz? tak, że jeśli uruchomię następujące w Pythonie:

>>> import my_module
>>> do_stuff(1)

otrzymuję następny monit dotyczący zakresu i kontekstu, w którym mam komentarz do_stuff()?

aaronstacy
źródło
Możliwy duplikat wejścia w tryb interaktywny w Pythonie
Mad Physicist

Odpowiedzi:

61

Wstawianie

import pdb; pdb.set_trace()

wejdzie w tym momencie do debugera Pythona

Zobacz tutaj: http://docs.python.org/library/pdb.html

prestomation
źródło
pdbjest świetnym pytonem waniliowym; jeśli masz miejsce na wprowadzenie zewnętrznego pakietu, ipdbjest świetny - ta sama funkcjonalność co debugger, ale z podświetlaniem składni, uzupełnianiem kart itp. ipython
khstacking
Aktualizacja - ipdbzostała wycofana, obecnie używam pdbpp( pdb++) , która ma podobne funkcje i działa z import pdb; pdb.set_trace()(tj. Łata ten import, więc jest to zamiennik typu drop-in)
driftcatcher
@hangtwenty: dlaczego według ciebie ipdbzostało wycofane? Nie mogę znaleźć żadnych wiadomości na ten temat.
Nick Matteo
@Kundor huh, masz rację. Wyraźnie pamiętam, że czytałem gdzieś, że autorzy postanowili zaprzestać utrzymywania projektu i wskazali inny projekt do wykorzystania. Może wydarzyło się to na chwilę, a potem zostało wskrzeszone? Mogę się mylić! W każdym razie cieszyłem się ipdbwcześniej, ale pdbpp
cieszę
143

Jeśli potrzebujesz standardowego interaktywnego monitu (zamiast debuggera, jak pokazano w prestomation), możesz to zrobić:

import code
code.interact(local=locals())

Zobacz: moduł kodu .

Jeśli masz zainstalowany IPython i chcesz zamiast tego mieć powłokę IPython, możesz to zrobić dla IPython> = 0.11:

import IPython; IPython.embed()

lub dla starszych wersji:

from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()
ipshell(local_ns=locals())
Matt Anderson
źródło
27
dla IPython> = 0.11, nie ma już powłoki modułu w IPythonie ... więc uruchom go za pomocą polecenia „import IPython; IPython.embed ()”.
evandrix,
Czy można kontynuować po wejściu code.interact(), a la PDB c(ontinue)?
Nick T
4
code.interact()jest połączeniem blokującym. Twój program zatrzyma się i zaczeka na zakończenie. Jeśli wyjdziesz z interaktywnego interpretera, program powinien wznowić działanie z instrukcją występującą bezpośrednio po nim.
Matt Anderson,
1
Jaka jest różnica między interaktywnym monitem a debugerem?
StockB
1
@StockB To standardowa interaktywna podpowiedź, która sprawia, że ​​jest to ważne. Debugger jest interaktywny szybki, ale to nie to samo. W PDB nie można wykonywać instrukcji wielowierszowych, funkcja wbudowana jest nadpisywana itp.help
kbrose
29

Jeśli potrzebujesz domyślnego interpretera Pythona, możesz to zrobić

import code
code.interact(local=dict(globals(), **locals()))

Umożliwi to dostęp zarówno do lokalnych, jak i globalnych.

Jeśli chcesz skorzystać z interpretera IPythona, IPShellEmbedrozwiązanie jest przestarzałe . Obecnie działa:

from IPython import embed
embed()
Ronan Paixão
źródło
8
dzięki, code.interact(local=dict(globals(), **locals()))jest o wiele lepsze niż to, code.interact(local=locals())że to drugie sprawia, że ​​ponownie importujesz pakiety
s2t2
Ta odpowiedź zadziałała lepiej, ponieważ użyłem skryptu bash do wywołania mojego kodu w Pythonie. Nie mogłem wejść w interakcję z moim kodem Pythona przy użyciu zaakceptowanej odpowiedzi. Dzięki!
jonathanking