2008-10-23 13 views
34

Python jest całkiem fajny, ale niestety jego debugger nie jest tak dobry jak perl -d.Debuger w języku Python: wchodzenie w funkcję, którą wywołałeś interaktywnie

Jedno, co robię bardzo często podczas eksperymentowania z kodem jest wywołanie funkcji z poziomu debuggera, i krok w tej funkcji, tak jak poniżej:

# NOTE THAT THIS PROGRAM EXITS IMMEDIATELY WITHOUT CALLING FOO() 
~> cat -n /tmp/show_perl.pl 
1 #!/usr/local/bin/perl 
2 
3 sub foo { 
4  print "hi\n"; 
5  print "bye\n"; 
6 } 
7 
8 exit 0; 

~> perl -d /tmp/show_perl.pl 

Loading DB routines from perl5db.pl version 1.28 
Editor support available. 

Enter h or `h h' for help, or `man perldebug' for more help. 

main::(/tmp/show_perl.pl:8): exit 0; 

# MAGIC HAPPENS HERE -- I AM STEPPING INTO A FUNCTION THAT I AM CALLING INTERACTIVELY 
    DB<1> s foo() 
main::((eval 6)[/usr/local/lib/perl5/5.8.6/perl5db.pl:628]:3): 
3:  foo(); 


    DB<<2>> s 
main::foo(/tmp/show_perl.pl:4):  print "hi\n"; 


    DB<<2>> n 
hi 
main::foo(/tmp/show_perl.pl:5):  print "bye\n"; 


    DB<<2>> n 
bye 


    DB<2> n 
Debugged program terminated. Use q to quit or R to restart, 
    use O inhibit_exit to avoid stopping after program termination, 
    h q, h R or h O to get additional info. 

    DB<2> q 

Jest to niezwykle przydatne podczas próby krok po kroku obsługa różnych danych wejściowych w celu wyjaśnienia przyczyny niepowodzenia. Jednak wydaje się, że nie działa on ani w pdb, ani pydb (pokazałbym równoważny przykład z pythona do powyższego, ale spowodował duży zrzut stosu wyjątków).

Więc moje pytanie jest dwojaki:

  1. Am I czegoś brakuje?
  2. Czy istnieje debuger w języku Python, który rzeczywiście pozwoliłby mi to zrobić?

Oczywiście mogłem umieścić wywołania w kodzie osobiście, ale uwielbiam pracować interaktywnie, np. nie trzeba zaczynać od zera, gdy chcę spróbować wywołać z nieco innym zbiorem argumentów.

+1

czy możesz zaakceptować ostatnią odpowiedź? – sureshvv

+0

OP odpowiedział na swoje pytanie na dole: https://stackoverflow.com/a/228653/5512755 – Dunatotatos

Odpowiedz

29

I odpowiedziałem na własne pytanie! To polecenie „debug” w pydb:

~> cat -n /tmp/test_python.py 
    1 #!/usr/local/bin/python 
    2 
    3 def foo(): 
    4  print "hi" 
    5  print "bye" 
    6 
    7 exit(0) 
    8 

~> pydb /tmp/test_python.py 
(/tmp/test_python.py:7): <module> 
7 exit(0) 


(Pydb) debug foo() 
ENTERING RECURSIVE DEBUGGER 
------------------------Call level 11 
(/tmp/test_python.py:3): foo 
3 def foo(): 

((Pydb)) s 
(/tmp/test_python.py:4): foo 
4  print "hi" 

((Pydb)) s 
hi 
(/tmp/test_python.py:5): foo 
5  print "bye" 


((Pydb)) s 
bye 
------------------------Return from level 11 (<type 'NoneType'>) 
----------------------Return from level 10 (<type 'NoneType'>) 
LEAVING RECURSIVE DEBUGGER 
(/tmp/test_python.py:7): <module> 
3

Jest python debugger, który jest częścią dystrybucji rdzenia Pythona o nazwie „PDB”. Rzadko używam go sam, ale czasami jest przydatny.

Biorąc pod uwagę ten program:

def foo(): 
    a = 0 
    print "hi" 

    a += 1 

    print "bye" 

foo() 

Oto sesja debugowania go:

$ python /usr/lib/python2.5/pdb.py /var/tmp/pdbtest.py   ~ 
> /var/tmp/pdbtest.py(2)<module>() 
-> def foo(): 
(Pdb) s 
> /var/tmp/pdbtest.py(10)<module>() 
-> foo() 
(Pdb) s 
--Call-- 
> /var/tmp/pdbtest.py(2)foo() 
-> def foo(): 
(Pdb) s 
> /var/tmp/pdbtest.py(3)foo() 
-> a = 0 
(Pdb) s 
> /var/tmp/pdbtest.py(4)foo() 
-> print "hi" 
(Pdb) print a 
0 
(Pdb) s 
hi 
> /var/tmp/pdbtest.py(6)foo() 
-> a += 1 
(Pdb) s 
> /var/tmp/pdbtest.py(8)foo() 
-> print "bye" 
(Pdb) print a 
1 
(Pdb) s 
bye 
--Return-- 
> /var/tmp/pdbtest.py(8)foo()->None 
-> print "bye" 
(Pdb) s 
--Return-- 
> /var/tmp/pdbtest.py(10)<module>()->None 
-> foo() 
(Pdb) s 
2

Na interaktywnej pracy nad kodem Zajmuję, zazwyczaj uważają, że bardziej efektywne ustawienie programowe " break point "w samym kodzie z pdb.set_trace. To sprawia, że ​​łatwiej jest przełamać stan programu w głębi pętli: if <state>: pdb.set_trace()

+0

Zobacz także http://stackoverflow.com/questions/150375/how-do-you-break-into-the-debugger -z-Pythona-kod źródłowy –

17

Możesz również interaktywnie debugować funkcję za pomocą pdb, pod warunkiem, że skrypt, który chcesz debugować, nie zostanie zakończony() na końcu:

$ cat test.py 
#!/usr/bin/python 

def foo(f, g): 
     h = f+g 
     print h 
     return 2*f 

do debugowania, rozpocząć sesję interaktywną Pythona i import WPB:

$ python 
Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import pdb 
>>> import test 
>>> pdb.runcall(test.foo, 1, 2) 
> /Users/simon/Desktop/test.py(4)foo() 
-> h = f+g 
(Pdb) n 
> /Users/simon/Desktop/test.py(5)foo() 
-> print h 
(Pdb) 

moduł PDB pochodzi z pytona i jest udokumentowany w modułach docs na http://docs.python.org/modindex.html

3

Jeśli znasz lepiej debuggera GUI, istnieje winpdb ("wygrana" w tym przypadku nie odnosi się do systemu Windows). Używam go w Linuksie.

na Debianie/Ubuntu:

sudo aptitude install winpdb 

Następnie wystarczy umieścić to w kodzie, w którym chcesz go złamać:

import rpdb2; rpdb2.start_embedded_debugger_interactive_password() 

następnie rozpocząć winpdb i dołączyć do uruchomionego skryptu.

+0

Dzięki. Nie wiedziałem o tym! – Ben

+0

Do tej pory działa tylko dla Pythona2.7. https://bugs.launchpad.net/ubuntu/+source/winpdb/+bug/1126411 –