8

例外に関連するイディオムとアンチイディオムに関するPythonのドキュメントによると、次のようになります。主な機能のキャッチオール。」この文をセクションに分けて...

「コード内で使用する以外の句はできるだけ少なくする必要があります」

私のような初心者にとっては少し混乱しますが、PythonではEAFPスタイル(つまり、多くtryのステートメント)を使用するのが良い習慣だと思いましたexcept。それとも私はポイントを逃していますか?

「あなたが使用するものは通常、常に成功するはずの内部呼び出しになります」

ここでの指摘がわかりません。

「またはメイン関数のキャッチオール。」

したがって、例外をスローするletコードは、実際に一般的な例外処理が行われるトップレベルに到達するまで、コールスタックに渡すだけの良いスタイルですか?

4

4 に答える 4

2

「コード内で使用する以外の句はできるだけ少なくする必要があります」

例外を除いて、コードを散らかすのは簡単です。

def solve_linear(mat1, mat2):
    det1 = determinant(mat1)
    det2 = determinant(mat2)
    try:
        return det1 / det2
    except ZeroDivisionError:
        raise NoSolution

ZeroDivisionErrorここでは、伝播させるのはおそらく問題ありません。あなたはそれを捕まえる必要はありません。

「あなたが使用するものは通常、常に成功するはずの内部呼び出しになります」

たとえば、ファイルを読み取る、またはキャッシュされた値を返すこのコードを見てください。KeyError例外にもかかわらず、通常は成功します。

def read_file(path):
    try:
        return cache[path]
    except KeyError:
        fp = open(path, 'rb')
        data = fp.read()
        fp.close()
        cache[path] = data
        return data

「またはメイン関数のキャッチオール。」

プログラムがインタラクティブである場合は、おそらくトップレベルでほとんどすべてをキャッチしたいと思うでしょう。インタラクティブなコマンドラインプログラムのトップループは次のとおりです。

def main():
    while True:
        try:
            text = raw_input('enter command: ')
            cmd = parse_command(text)
        except EOFError:
            return
        except KeyboardInterrupt:
            return
        except ValueError:
            print 'Syntax error'
            continue

        try:
            run_cmd(cmd)
        except SystemExit:
            raise
        except Exception:
            traceback.print_exc()
于 2012-10-25T17:48:05.960 に答える
1

最初の点に関して、例外を使用することの全体的なポイントは、すべての行を1つにまとめる必要がないということです。たとえばCの場合、エラーは通常、関数呼び出しの戻り値によって決定されます。したがって、すべてのエラーをキャッチしたい場合は、すべての呼び出しの後にそれらをチェックする必要があります。Pythonを使用すると、try / exceptionブロックにまとめられ、すべてのエラーを1回だけ処理するステートメントの(おそらく大きな)ブロックをグループ化できます。

2番目のポイントは、(可能であれば)障害が発生したポイントの近くで障害を解決したいということです。たとえば、ネットワークからデータを読み取っていて、ゼロバイトを取得しているとします。その場合、通常は待ってから再試行してもまったく問題ありません。

最後のポイントは、エラーが大きすぎて低レベルで処理できない場合があるということです。たとえば、存在しないファイルを開こうとすると失敗します。そして、あなたのプログラムは、ファイルの内容に対して何をしようとしていたのかを実行できません。プログラムのトップレベルでそれを処理し、ユーザーに別のファイル名を尋ねるか、プログラムを終了するのが最善です。

于 2012-10-25T17:38:32.710 に答える
1

Pythonの哲学は通常、「許可ではなく、許しを求める」ことです。ただし、考えられるすべてのエラーをキャッチするためにtry-except句を使用するのではありません。理想的には、各try-exceptは、関連するエラーのみをキャッチします。

悪い(特定の例外タイプを指定しません):

a = [1, 2, 3]
i = 3
try:
    print a[i]
except:
    print "Not found!"

GOOD(取得する予定の例外のみを処理します):

a = [1, 2, 3]
i = 3
try:
    print a[i]
except IndexError:
    print "Not found!"

これが重要である理由は、他の考えられるコードエラーを隠さないためです。この例でi1.8だった場合はどうなりますか?Not Found!最初の例は実際の問題を覆い隠して印刷しますが、2番目の例はTypeError: list indices must be integers, not floatコードに論理的な欠陥があることを知らせて戻ってきます。

于 2012-10-25T17:42:39.583 に答える
1

重要なのは、例外は「例外的な」状況でのみ使用されるべきだということです。これが、「通常は成功する呼び出しで」の使用の背後にある意味です。この例としては、非常に奇妙な状況下でゼロ除算を実行しなければならない計算があります。次に、その可能性に対処するために、それをtry/exceptステートメントで囲むことができます。

main関数のキャッチオールは、同じシナリオに適用できます。計算がコールスタックのどこかでゼロ除算になってしまうとしましょう。この時点から続行することはできないため、失敗した時点でtry/exceptステートメントを使用しても意味がありません。エラーから合理的に回復できる、より高いレベルに1つだけ持つ方が理にかなっています。

彼らがドキュメントで示している例は、この例です。'get_status'を呼び出すときは、ファイルがそこにあることを期待します。そうでない場合は、それを処理するためのexceptステートメントがあります(ただし、前述のように、その特定のケースでは、「with」ステートメントの方がはるかに優れています)。

于 2012-10-25T17:36:22.173 に答える