ベスト プラクティスはassert
、コードが正しい場合に決して発生しない条件に使用することと、少し珍しいが発生する可能性がある条件 (たとえば、メモリが不足している場合、ユーザー入力が無効な場合、または外部接続が切断されます)。私は、この慣行の背後にある理論的根拠を次のように理解しています。
assert
-O インタープリター フラグで無効になります。外的要因から生じる可能性のある状態を黙って無視してはならないため、不適切であると断言します。OTOH、私のコードが正しくない場合にのみ発生する可能性のある状態は、テストとデバッグを通じてうまくいけば解消されるので、問題ありませんassert
。assert
AssertionError
通常、「キャッチしないでください。これは壊滅的な失敗です」と解釈されるため、呼び出し元が例外を処理することを思いとどまらせます。さらに、キャッチするにはあまりにも一般的です。これは、バグが見つかった場合に最適です。そのための典型的な処理は、実行を停止してコードをデバッグすることです。それが外的要因による一般的な状態である場合は良くありません。
特定の関数引数が常に正であることを保証するコードを書くとします。負の値であることがわかった場合は、明らかにコードに誤りがあります。したがって、私はassert
議論が肯定的であることに行きます。
後で、誰かが別のアプリケーションでこの機能が役立つことに気付きます。彼らはそれをインポートし、あらゆる種類のデータをそれに送信します。私の関数の観点からすると、実際には負の値を受け取る可能性が非常に高くなります。これは単に無効なユーザー入力です。おそらく、assert
はもはや適切ではなく、例外に置き換える必要があります。
ほとんどすべてのコードは、ある日、私の知らないうちに再利用される可能性があるため、この議論は「決して使用しないassert
でください。例外のみを使用してください」と言っているようです。明らかに、これは受け入れられた慣習ではありません。私は何が欠けていますか?
編集:
より具体的には、関数が負の引数をまったく処理できないとしましょう。したがって、引数が負になると、関数は次のいずれかを実行します。
- 例外を発生させる
- アサートに失敗する
- 実行を継続し、誤った出力を生成する可能性があります
負の引数が呼び出し元によってキャッチされた場合、どのように素晴らしいかがわかります。しかし、関数の呼び出しがコードの何十箇所にも散在している場合、同じチェックが何度も繰り返されるため、コードの明瞭さが損なわれることはほぼ間違いありません。(もちろん、うっかり忘れてしまうこともあります。)