web-dev-qa-db-ja.com

なぜアサートがあまり使われていないのですか?

Pythonのassertステートメント は、 が発生してはならない状況 を捕捉するための良い方法であることがわかりました。また、コードが正しいと信頼されている場合は、Python最適化によって削除できます。

Pythonアプリケーションをデバッグモードで実行するのに最適なメカニズムのようです。しかし、いくつかのPython Django、twisted、zopeなどのプロジェクトを見ると、assertはほとんど使用されていませんが、なぜこれが発生するのですか?

Pythonコミュニティで頻繁にアサートステートメントが使用されないのはなぜですか?

60
Carlo Pires

assertが頻繁に使用されない主な理由は、誰もPythonの「最適化された」モードを使用していないだと思います。

アサートは、プログラミングの間違いを検出し、予期しない状況から身を守るための優れたツールですが、このすべてのエラーチェックにはコストが伴います。 C/C++などのコンパイル済み言語では、アサートはデバッグビルドでのみ有効になり、リリースビルドから完全に削除されるため、これは実際には問題になりません。

一方、Pythonでは、debugモードとreleaseモードの間に厳密な区別はありません。インタプリタは「最適化フラグ」(-O)を備えていますが、現在これは実際にはバイトコードを最適化せず、アサートを削除するだけです。

したがって、ほとんどのPythonユーザーは-Oフラグを無視し、スクリプトを "通常モード"で実行します種類アサートはデバッグモードであるため有効であり、__debug__Trueですが、「製品版」と見なされます。

おそらく、ロジックを切り替える、つまりデフォルトで「最適化」し、明示的なデバッグモード(*)でのみアサートを有効にする方が賢明ですが、これは多くのユーザーを混乱させ、このような変更が発生することはないと思います。

((*)これは、例えば、Java VMが-ea(アサーションを有効にする)スイッチを特徴とすることにより、どのように行うかです。)

58
Ferdinand Beyer

いくつかの理由が思い浮かびます...

これは主要な機能ではありません

多くのプログラマーは、理論的根拠にとらわれず、プログラムの最後から2番目の機能に直接参加していないものはすべて無視します。 assertステートメントはデバッグとテストを目的としているため、手に負えないほどの贅沢です。

単体テスト

Assertステートメントは、単体テストの台頭に先んじています。 assertステートメントにはまだ用途がありますが、ユニットテストは現在、サブルーチンとそのシステムからがらくたを打ち消すような敵対的な環境を構築するために広く使用されています。これらの状況下では、言明は銃撃戦のナイフのように感じ始めます。

テストに対する業界の尊敬の向上

Assertステートメントは、防御の最終行として最適です。 C言語では、その言語が世界を支配していたときに、新しくて複雑な「防御的プログラミング」を実装するための優れた方法として、それは高くて手に負えないほどの高さになりました。危機に瀕している瞬間に壊滅的な災害を認識してトラップします。これは、テストの価値が広く認識され、尊重されるようになる前のことであり、災害はかなり一般的です。

今日、真面目な商用ソフトウェアを何らかの形でテストすることなくリリースすることは、前代未聞です。テストは真剣に受け止められ、大規模な分野へと進化しました。大きなチェックリストと正式な承認があるテスト専門家と品質保証部門があります。これらの条件下では、プログラマーはアサーションに煩わされない傾向があります。なぜなら、コードが非常に面倒なテストにかけられ、奇妙な災害の可能性が無視できるほど離れているためです。それが正しいと言っているわけではありませんが、もし怠惰なプログラミングのせいがQA部門に移されるのであれば、どうしてでしょうか。

32
John Mee

私はこれらのプロジェクトの作者ではないので、これは自分の経験に基づく推測にすぎません。それらのプロジェクトの人々に直接尋ねなければ、具体的な答えは得られません。

アサートは、独自のアプリケーションでデバッグなどを行う場合に最適です。ただし、提供したリンクで述べたように、アプリケーションが状態を予測して回復できる場合は、条件付きを使用する方が適切です。私はzopeを使用していませんが、TwistedとDjangoの両方で、それらのアプリケーションはコードの多くのエラーから回復して続行できます。ある意味では、アサーションを実際に処理できるため、アサーションはすでに「コンパイル」されています。

これに関連するもう1つの理由は、リストしたライブラリなどの外部ライブラリを使用するアプリケーションがエラー処理を実行したい場合があることです。ライブラリがアサーションを使用するだけの場合、どのようなエラーであっても、AssertionErrorが発生します。条件付きの場合、ライブラリは実際に、アプリケーションでキャッチおよび処理できる有用なエラーをスローする可能性があります。

12
Michael Pratt

私の経験によれば、assertsは主にプログラムの開発段階で使用され、ユーザー定義の入力をチェックします。 assertsは、プログラミングエラーをキャッチするために実際には必要ありません。 Python自体は、ZeroDivisionError, TypeError とか、ぐらい。

0
NGB