2012-03-29 10 views
2

プログラム状態の多くのチェックを行います。その失敗はコードのバグを示します。そのような場合、私はif not condition: raise MyExceptionよりも読みやすいので、assert conditionを使いたいと思っています。-O(最適化)フラグにもかかわらずアサートを維持

raiseの代わりにassertを使用することには2つの問題があります。

  1. assertので、それは後で(AssertionErrorをキャッチすることは、あまりにも多くをキャッチすること)が困難となるキャッチ、上げるべき例外を指定することはできません。

  2. assertは、-Oフラグがインタープリタに渡されると無効になります。

私の環境では、コード内のバグは、バグが特定されて修正されるまで、結果を破棄する必要があります。したがって、上記のチェックによって発生した例外をキャッチするポイントはありません。したがって、問題#1は私の状況では無関係です。

問題#2は深刻です。私は自分の小切手を生産コードに残しておきたい。なぜなら、私の環境では、正確さがパフォーマンスよりもはるかに重要だからだ。今日、-Oフラグを使用する人はほとんどいません。ある日、私や他の誰かが(例えば、if __debug__の背後にあるコードを抑制するために、または-Oが実際にコードを最適化するために)使用することを好むかもしれません。すべての私のassertステートメントはプロダクションコードでアクティブなままでなければならないので、私はすべてのassertステートメントを別のものに置き換える必要があります。 -Oフラグにもかかわらずassertを強制的に保持する方法はありますか?

ちなみに、私はassertの動作を、アサーションの原因となった行から変数値を出力することによってカスタマイズする予定です。 sys.excepthookAssertionErrorをキャッチし、トレースバックを読み取り、関連するソースコードを見つけて、関連する行から変数を出力し、例外を再現する私の独自の関数に置き換えることによって、私はそれを行うことができると思います。もし誰かがそれに問題があるのなら、教えてください。

+0

を私はあなたが致命的な障害状態を識別するために 'assert'を使用していると仮定し、だけではなく、通常の例外条件? –

+0

正確に。私は珍しい入力などを捕らえるのにまだ適切な例外を使っています - 私は 'assert'を使ってコードの誤りをキャッチしています。私の特定の環境では、コードの間違いは致命的なエラーとみなされます(生産コードは既知のバグを含んでいれば実行できませんが、マイナーなものです)。 – max

+0

それは良く見えません。アサーションを削除することは、明らかに-Oスイッチの「機能」です。 http://stackoverflow.com/q/1273211/102937 –

答えて

3

アサーションが必要なものでない場合は、アサーションを使用しないでください。代わりに、何らかの条件に違反した場合にこの例外をスローすることを明示してください。 assertステートメントには、常に「私は実行されているかもしれないし、実行されていないかもしれない」という側面があります。これは、ハッキーではなく、驚異的でなく、将来的に破損する可能性が低く、ユーザーが-Oを追加するのを防ぐ必要はありません。

入力を保存したいだけなら、それを行うことができます。 (より具体的な名前を強くお勧めします)このような関数を作成し、assertの代わりに使用:

def require(cond, msg): 
    if not cond: 
     raise MyException(msg) 
関連する問題