2

ベスト プラクティスはassert、コードが正しい場合に決して発生しない条件に使用することと、少し珍しいが発生する可能性がある条件 (たとえば、メモリが不足している場合、ユーザー入力が無効な場合、または外部接続が切断されます)。私は、この慣行の背後にある理論的根拠を次のように理解しています。

  1. assert-O インタープリター フラグで無効になります。外的要因から生じる可能性のある状態を黙って無視してはならないため、不適切であると断言します。OTOH、私のコードが正しくない場合にのみ発生する可能性のある状態は、テストとデバッグを通じてうまくいけば解消されるので、問題ありませんassert

  2. assertAssertionError通常、「キャッチしないでください。これは壊滅的な失敗です」と解釈されるため、呼び出し元が例外を処理することを思いとどまらせます。さらに、キャッチするにはあまりにも一般的です。これは、バグが見つかった場合に最適です。そのための典型的な処理は、実行を停止してコードをデバッグすることです。それが外的要因による一般的な状態である場合は良くありません。

特定の関数引数が常に正であることを保証するコードを書くとします。負の値であることがわかった場合は、明らかにコードに誤りがあります。したがって、私はassert議論が肯定的であることに行きます。

後で、誰かが別のアプリケーションでこの機能が役立つことに気付きます。彼らはそれをインポートし、あらゆる種類のデータをそれに送信します。私の関数の観点からすると、実際には負の値を受け取る可能性が非常に高くなります。これは単に無効なユーザー入力です。おそらく、assertはもはや適切ではなく、例外に置き換える必要があります。

ほとんどすべてのコードは、ある日、私の知らないうちに再利用される可能性があるため、この議論は「決して使用しないassertでください。例外のみを使用してください」と言っているようです。明らかに、これは受け入れられた慣習ではありません。私は何が欠けていますか?

編集:

より具体的には、関数が負の引数をまったく処理できないとしましょう。したがって、引数が負になると、関数は次のいずれかを実行します。

  • 例外を発生させる
  • アサートに失敗する
  • 実行を継続し、誤った出力を生成する可能性があります

負の引数が呼び出し元によってキャッチされた場合、どのように素晴らしいかがわかります。しかし、関数の呼び出しがコードの何十箇所にも散在している場合、同じチェックが何度も繰り返されるため、コードの明瞭さが損なわれることはほぼ間違いありません。(もちろん、うっかり忘れてしまうこともあります。)

4

2 に答える 2

2

作成/再利用している関数が正または負の数値で有効な場合、それはアサートを含むべきメソッドではありません。再利用された関数を呼び出す関数は、関数に無効な値を提供する関数であるため、アサートする必要があります。

function x() {
   var i;
   // logic to set i. use assertion to test the logic.
   assert(i > 0);
   reusedFunc(i);
}

reusedFunc(i) が負の数で有効でない場合、負の値が渡されると例外がスローされます。

于 2012-04-04T20:58:56.033 に答える
1

assertステートメントは、コードの開発およびデバッグ中に使用するためのものであり、重要な API の制約を保証するものではありません。

正の数の例では、値をテストしValueError、コード内で負の値を使用すると悪い結果が生じる場合は、有用なエラー メッセージで発生させます。

assert ステートメントは絶対に使用しないでくださいそれらは書くのは簡単ですが、それでもしばしば不適切です。

assertステートメントは、人々が長いものを書き、括弧を使用してステートメントとメッセージを複数行にまたがることを決定したときにも失敗します...これSyntaxWarningにより、作成者が不注意で (条件、メッセージ) を使用して作成したタプルについて、最新の Python で非-function ステートメントですが、常にそうしているわけではありません。

もう 1 つの経験則: が発生したことを確認する unittest が表示AssertionErrorされた場合、コードは assert を使用すべきではありません。

ステートメントを使用しない場合assert、これらのどれもあなたを噛むことはありません。

于 2012-04-06T01:41:12.580 に答える