24

Pythonライブラリで自分の例外を発生させると、例外スタックに発生行自体がスタックの最後の項目として表示されます。これは明らかにエラーではなく、概念的には正しいですが、コードを外部で、たとえばモジュールとして使用している場合、デバッグに役立たないことに焦点を当てています。

これを回避し、標準のPythonライブラリのように、Pythonに最後から最後までのスタックアイテムを最後のスタックアイテムとして表示させる方法はありますか?

4

3 に答える 3

7

当然の警告: インタープリターの動作を変更することは、一般的に嫌われます。いずれにせよ、エラーが発生した場所を正確に確認することは、特に関数がいくつかの異なる理由でエラーを発生させる可能性がある場合に、デバッグに役立ちます。

モジュールを使用し、カスタム関数にtraceback置き換えると、おそらくこれを行うことができます。sys.excepthookただし、変更を加えると、モジュールだけでなくプログラム全体のエラー表示に影響するため、おそらくお勧めできません。

コードを try/except ブロックに入れ、エラーを修正して再発生させることも検討できます。しかし、予期しないエラーが発生する可能性を低くし、発生する可能性のあるエラーについて有益なエラー メッセージを作成することに時間を費やしたほうがよいでしょう。

于 2010-12-12T00:55:58.370 に答える
4

Python で独自の例外フックを作成できます。以下は、私が使用しているコードの例です。

import sys
import traceback

def exceptionHandler(got_exception_type, got_exception, got_traceback):
    listing  = traceback.format_exception(got_exception_type, got_exception, got_traceback)
    # Removing the listing of statement raise (raise line). 
    del listing[-2]
    filelist = ["org.python.pydev"] # avoiding the debuger modules.
    listing = [ item for item in listing if len([f for f in filelist if f in item]) == 0 ]
    files = [line for line in listing if line.startswith("  File")]
    if len(files) == 1:
        # only one file, remove the header.
        del listing[0]
    print>>sys.stderr, "".join(listing)

以下は、カスタム例外コードで使用したいくつかの行です。

sys.excepthook = exceptionHandler
raise Exception("My Custom error message.")

メソッドの例外では、不要なファイルを無視する場合は、ファイル名またはモジュール名をリスト「ファイル名」に追加できます。Eclipseでpydevデバッガーを使用しているため、python pydevモジュールを無視しました。

上記は、特定の目的のために私自身のモジュールで使用されています。モジュールに変更して使用できます。

于 2016-11-25T07:12:11.523 に答える
-2

例外メカニズムを使用して引数を検証しないことをお勧めします。例外を条件としてコーディングすることは、「開発者として、提供された引数が引き起こす可能性のあるすべての悪い条件を考えていない場合、アプリをクラッシュさせる。おそらく、制御できないものだけでなく、 OS やハードウェア、Python 言語などの制御下にある方がより論理的かどうかはわかりませんが、実際には、解決策を要求するときに例外を使用します。

あなたの質問に答えるために、部分的には、次のようにコーディングするのと同じくらい簡単です:

class MyObject(object):
    def saveas(self, filename):
        if not validate_filename(filename):
            return False
        ...

発信者

if not myobject.saveas(filename): report_and_retry()

おそらく素晴らしい答えではないかもしれませんが、考えてみてください。

于 2015-06-12T21:11:30.213 に答える