9

コードの実行中に発生する警告をデバッグしたいと考えています。

最初の警告が発生する前に警告なしで何百万回も警告が発生する行が実行されるため、単純なブレークポイントは機能しません。

また、これが発生している行はライブラリ コード (より正確にはpandas/core/common.py) にあるため、コードをまったく変更しないことをお勧めします。

プログラムが警告を発したときにプログラムの実行を停止し、この時点でスタックを検査したいだけpdbですipdb

警告の発行時に、いずれかのデバッガーが自動的にシングル ステップ モードに入るように構成する方法はありますか?

4

4 に答える 4

11

スクリプトを書くことができますdbg.py:

import pdb, warnings, sys
import __builtin__

if __name__ == '__main__':
    args, n = [], len(sys.argv)
    if n < 2:
        sys.exit(1)
    elif n > 2:
        args.append(__builtin__.__dict__[sys.argv[2]])
        if n > 3:
            args.append(int(sys.argv[3]))
    warnings.simplefilter('error', *args)  # treat warnings as exceptions
    try:
        execfile(sys.argv[1])
    except:
        pdb.post_mortem(sys.exc_info()[-1])

その後、それを使用してスクリプトをそのようにデバッグできます。警告が発生した場合に pdb を実行する場合は、最初の引数としてスクリプト名を渡します。

$ python dbg.py yourscript.py

特定の種類の警告が発生したときにのみ pdb を実行する場合は、2 番目の引数として警告の種類を渡します。

$ python dbg.py yourscript.py DeprecationWarning

3 番目の引数としての行番号:

$ python dbg.py yourscript.py DeprecationWarning 342

warnings.filterwarnings代わりにを使用してコードを書き直して、warnings.simplefilter警告のフィルタリングをさらに柔軟にすることもできます。

于 2015-12-21T23:31:17.323 に答える
2

https://pypi.python.org/pypi/rpdb/

rpdbプログラムの起動を制御できない場合、このような問題をデバッグするのに非常に便利であることがわかりました。必要なのは一時的に変更pandas/core/common.pyして追加することです

import rpdb
debugger = rpdb.Rpdb(port=12345)
debugger.set_trace()

警告がトリガーされると、デバッガーは接続を待機します。次に、デバッガーに接続してスタックを調べます。

于 2015-12-21T19:23:10.640 に答える
2

警告をエラーとして処理する代わりに、warnings.catch_warnings リンクを使用して警告リストにアクセスし、警告をスローするコードの範囲を特定できる場合は、実行を PDB セッションに切り替えることができます。

ただし、問題のあるコード スニペットの後で警告リストの警告番号の変更を検出したときに実行を中断するブレークポイントを設定して、PDB でプログラムを開始することをお勧めします。デバッグ コード スニペットがループ内にある場合は、メリットがあります。

例:

import warnings

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter('always')
    warningNum = len(w)
    for i in range(someNumber):
        "your code probably throw warning"

        if len(w) != warningNum:
            warningNum = len(w) #set break point here

でスクリプトを実行python -m pdb yourscript.pyし、行にブレークポイントを設定すると、warningNum = len(w)警告番号の変更を検出したときに実行を一時停止できます。

于 2018-11-06T00:41:46.290 に答える