Python довольно крут, но, к сожалению, его отладчик не так хорош, как perl -d.
Одна вещь, которую я очень часто делаю, экспериментируя с кодом, - это вызов функции из отладчика и переход к этой функции, например:
# 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
Это невероятно полезно, когда вы пытаетесь выполнить пошаговую обработку различных входных данных функцией, чтобы выяснить, почему она терпит неудачу. Однако, похоже, он не работает ни в pdb, ни в pydb (я бы показал пример Python, эквивалентный приведенному выше, но это приводит к большому дампу стека исключений).
Итак, у меня двоякий вопрос:
Очевидно, я мог бы сам поместить вызовы в код, но мне нравится работать в интерактивном режиме, например. не нужно начинать с нуля, когда я хочу попробовать вызвать с немного другим набором аргументов.
OP ответил на его вопрос внизу: stackoverflow.com/a/228653/5512755






И я ответил на свой вопрос! Это команда «отладки» в 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>
Существует отладчик python, который является частью основного дистрибутива python, который называется pdb. Сам редко пользуюсь, но иногда нахожу полезным.
Учитывая эту программу:
def foo():
a = 0
print "hi"
a += 1
print "bye"
foo()
Вот сеанс его отладки:
$ 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
Для интерактивной работы над кодом, который я разрабатываю, я обычно считаю более эффективным установить программную «точку останова» в самом коде с помощью pdb.set_trace. Это также упрощает прерывание состояния программы глубоко в цикле: if <state>: pdb.set_trace()
См. Также stackoverflow.com/questions/150375/…
Вы также можете отлаживать функцию в интерактивном режиме с помощью pdb, при условии, что сценарий, который вы хотите отладить, в конце не выполняет exit ():
$ cat test.py
#!/usr/bin/python
def foo(f, g):
h = f+g
print h
return 2*f
Для отладки запустите интерактивный сеанс Python и импортируйте pdb:
$ 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)
Модуль pdb поставляется с python и задокументирован в документации модулей по адресу http://docs.python.org/modindex.html.
pdb.run или pdb.runeval остановятся на первой строке кода, в то время как pdb.runcall не остановится, что может просто вернуть ошибку при отладке, и нам понадобится% debug для посмертной проверки, а не желаемый шаг.
Если вы более знакомы с отладчиком графического интерфейса, есть winpdb («win» в данном случае не относится к Windows). Я действительно использую его в Linux.
В debian / ubuntu:
sudo aptitude install winpdb
Затем просто вставьте это в свой код, где вы хотите, чтобы он сломался:
import rpdb2; rpdb2.start_embedded_debugger_interactive_password()
Затем запустите winpdb и подключитесь к вашему работающему скрипту.
Спасибо. Я не знал об этом!
Пока это работает только для python2.7. bugs.launchpad.net/ubuntu/+source/winpdb/+bug/1126411
не могли бы вы принять последний ответ?