web-dev-qa-db-ja.com

pythonエラー時に自動的にデバッガーを開始

これは私が長い間疑問に思っていた質問ですが、まだ適切な解決策を見つけることができませんでした。スクリプトを実行して、遭遇した場合、IndexErrorとしましょう。pythonは、行、場所、エラーの簡単な説明を出力して終了します。エラーが発生したときにpdbを自動的に起動することは可能ですか?ファイルの先頭に余分なimportステートメントを追加したり、数行のコードを追加したりすることには反対しません。

186
jeremy

traceback.print_exc を使用して、例外トレースバックを出力できます。次に sys.exc_info を使用してトレースバックを抽出し、最後にそのトレースバックで pdb.post_mortem を呼び出します

import pdb, traceback, sys

def bombs():
    a = []
    print a[0]

if __== '__main__':
    try:
        bombs()
    except:
        extype, value, tb = sys.exc_info()
        traceback.print_exc()
        pdb.post_mortem(tb)

code.interact でインタラクティブなコマンドラインを開始したい場合は、例外が発生したフレームのローカルを使用します

import traceback, sys, code

def bombs():
    a = []
    print a[0]

if __== '__main__':
    try:
        bombs()
    except:
        type, value, tb = sys.exc_info()
        traceback.print_exc()
        last_frame = lambda tb=tb: last_frame(tb.tb_next) if tb.tb_next else tb
        frame = last_frame().tb_frame
        ns = dict(frame.f_globals)
        ns.update(frame.f_locals)
        code.interact(local=ns)
111
Florian Bösch
python -m pdb -c continue myscript.py

-c continueフラグを指定しない場合、実行の開始時に 'c'(続行の場合)を入力する必要があります。その後、エラーポイントまで実行され、そこで制御が行われます。 eqzxで言及 のように、このフラグはpython 3.2の新しい追加であるため、以前のPythonバージョンには 'c'の入力が必要です( https://docs.python.org/3/library/pdb.html を参照)。

383

次のモジュールを使用します。

import sys

def info(type, value, tb):
    if hasattr(sys, 'ps1') or not sys.stderr.isatty():
    # we are in interactive mode or we don't have a tty-like
    # device, so we call the default hook
        sys.__excepthook__(type, value, tb)
    else:
        import traceback, pdb
        # we are NOT in interactive mode, print the exception...
        traceback.print_exception(type, value, tb)
        print
        # ...then start the debugger in post-mortem mode.
        # pdb.pm() # deprecated
        pdb.post_mortem(tb) # more "modern"

sys.excepthook = info

debug(または好きな名前)に名前を付けて、pythonパス)のどこかに配置します。

これで、スクリプトの開始時に、import debug

61
tzot

Ipythonには、この動作を切り替えるコマンドがあります:%pdb。それはあなたが説明したとおりに、おそらくもう少し(シンタックスの強調表示とコード補完でより有益なバックトレースを提供します)します。それは間違いなく試してみる価値があります!

39
Latanius

これはデバッガーではありませんが、おそらく同じくらい便利です(?)

Guidoがどこかのスピーチでこれについて言及しているのを知っています。

python-?)をチェックしました。-iコマンドを使用すると、スクリプトが停止した場所で対話できます。

したがって、このスクリプトを考えます:

testlist = [1,2,3,4,5, 0]

prev_i = None
for i in testlist:
    if not prev_i:
        prev_i = i
    else:
        result = prev_i/i

この出力を取得できます!

PS D:\> python -i debugtest.py
Traceback (most recent call last):
  File "debugtest.py", line 10, in <module>
    result = prev_i/i
ZeroDivisionError: integer division or modulo by zero
>>>
>>>
>>> prev_i
1
>>> i
0
>>>

正直に言うと、私はこれを使用していませんが、使用する必要があるため、非常に便利なようです。

30
monkut

IPythonは、コマンドラインでこれを簡単にします。

python myscript.py arg1 arg2

に書き換えることができます

ipython --pdb myscript.py -- arg1 arg2

または、同様に、モジュールを呼び出す場合:

python -m mymodule arg1 arg2

に書き換えることができます

ipython --pdb -m mymodule -- arg1 arg2

--に注意して、IPythonがスクリプトの引数を独自のものとして読み取らないようにします。

これには、pdbの代わりに拡張IPythonデバッガー(ipdb)を呼び出すという利点もあります。

17
wodow

IPython環境を使用している場合は、%debugを使用するだけで、シェルは検査などのためにipdb環境の問題のある行に戻ります。上記の別のオプションは、効果的に行うiPythonマジック%pdbを使用することです。同じ。

6
Jehandad

ipythonを使用している場合は、起動後に%pdb

In [1]: %pdb
Automatic pdb calling has been turned ON
5
Willemoes

次の行をコードに追加できます。

import pdb ; pdb.set_trace()

詳細: python任意の行でデバッガーを開始

4
Rory

python2.7のpython -m pdb script.pyを押し続けると、エラーが発生し、デバッグのためにそこで中断します。

3
Hannah

最初にcを入力せずに実行するには:

python -m pdb -c c <script name>

Pdbには独自のコマンドライン引数があります。-ccは、実行開始時にc(ontinue) commandを実行し、プログラムはエラーが発生するまで中断することなく実行されます。

3
Zlatko Karakaš

モジュールを実行している場合:

python -m mymodule

そして、例外が発生したときにpdbを入力したい場合は、次のようにします。

PYTHONPATH="." python -m pdb -c c mymodule/__main__.py

(またはextend your PYTHONPATH)。 PYTHONPATHモジュールを実行しているので、モジュールがパスで見つかるようにpdbが必要です。

1
dangonfast

階層の最上位の例外クラスのコンストラクター内にブレークポイントを配置すると、ほとんどの場合、エラーが発生した場所がわかります。

ブレークポイントを置くということは、それが何を意味するかを意味します。IDEを使用するか、pdb.set_trace、または何でも

0
vlad-ardelean