60

Python は非常に優れていますが、残念ながらそのデバッガーは perl -d ほど優れていません。

コードを試すときによく行うことの 1 つは、次のように、デバッガー内から関数を呼び出し、その関数にステップ インすることです。

# 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 の例を示しますが、大きな例外スタック ダンプが発生します)。

だから私の質問は2つあります:

  1. 何か不足していますか?
  2. 実際にこれを実行できるPythonデバッガーはありますか?

もちろん、自分で呼び出しをコードに入れることもできますが、インタラクティブに作業するのが大好きです。わずかに異なる引数のセットで呼び出しを試みたいときに、ゼロから始める必要はありません。

4

5 に答える 5

46

そして、私は自分の質問に答えました!これは、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>
于 2008-10-23T05:42:00.313 に答える
25

デバッグするスクリプトが最後に exit() されていない場合は、pdb を使用して関数を対話的にデバッグすることもできます。

$ 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のモジュール ドキュメントに記載されています。

于 2008-10-23T11:27:26.920 に答える
4

「pdb」と呼ばれる python のコア ディストリビューションの一部である python デバッガーがあります。私自身はめったに使用しませんが、時々便利だと思います。

このプログラムを考えると:

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
于 2008-10-23T05:46:25.470 に答える
2

GUIデバッガーに精通している場合は、winpdbがあります(この場合の「win」はWindowsを指しません)。私は実際にLinuxで使用しています。

debian / ubuntuについて:

sudo aptitude install winpdb

次に、これをコードの中断したい場所に配置します。

import rpdb2; rpdb2.start_embedded_debugger_interactive_password()

次に、winpdbを起動し、実行中のスクリプトにアタッチします。

于 2008-10-23T17:07:50.507 に答える
2

私が開発しているコードでインタラクティブな作業を行う場合、コード自体にプログラムによる「ブレークポイント」をpdb.set_trace. これにより、ループの奥深くでプログラムの状態を簡単に中断できます。 if <state>: pdb.set_trace()

于 2008-10-23T10:55:53.130 に答える