NotImplementedErrorを発生させる代わりにNotImplementedを返す理由


282

PythonにはというシングルトンがありNotImplementedます。

例外が発生するNotImplemented代わりに、なぜ誰かが戻りたいのでしょうかNotImplementedError?無効なメソッドを実行するコードなどのバグを見つけにくくするだけではないですか?

回答:


281

これは__lt__()、関連する比較方法がリストの並べ替えなどで間接的によく使用されるためです。アルゴリズムが別の方法を試すか、デフォルトの勝者を選ぶこともあります。例外を発生させると、キャッチされない限りソートから抜け出しますが、発生NotImplementedしないため、以降のテストで使用できます。

http://jcalderone.livejournal.com/32837.html

そのリンクを要約すると:

" NotImplementedは、操作を満たすために他の誰かに依頼する必要があることをランタイムに通知します。式でa == b、がa.__eq__(b)返されたNotImplemented場合、Pythonはを試行しb.__eq__(a)ますb。or Trueまたはを返すのに十分な知識がある場合False、式は成功できます。そうでない場合、ランタイムはフォールバックビルトイン(のIDに基づいて行動==して!=)。」


5
このリンクはドキュメントの終わり近くにあるため、注意して使用します。
Jason Coon、

16
Pythonインタープリターa.__eq__(b)がNotImplementedが返されたかどうかをチェックするとき、代わりにNotImplementedErrorを簡単にキャッチできませんでしたか(そして、b.__eq__(a)その後に呼び出しまたは何かを実行できません)?
Veky 2013

24
@Veky。例外を発生させると、オーバーヘッドが高くなる可能性があります。ソート操作のオーバーヘッドはリストのサイズによって拡大されるため、違いが非常に小さい場合でも、より高速な実装を見つけることには意味があります。また、ループを抜け出して、try / catchの実装で必要となるループに再入したくない場合もあります。
SpliFF

3
最初の点として、より高速な解決策は、常にNotImplementedを返すものを呼び出すのではなく、反転したgtとしてltを自動的に合成することです。Pythonはそれを行いません。ここでは速度が理由ではないと思います。そして、2つ目は、あなたの言っていることが理解できません。returnでは、raiseと同じくらいループを抜ける必要があります。実際、returnは、呼び出し側のスコープで常にキャッチされる特別なReturn例外を発生させると考えることができます。
Veky 2013

2
>>「リストのサイズで拡大」少なくとも、O(n)ソートがない限り、世界は知っておくべきです。
Jonathan Hartley、

106

ユースケースが異なるためです。

ドキュメントの引用(Python 3.6):

実装されていません

バイナリの特別なメソッド(例: __eq__()__lt__()__add__()__rsub__()、など)の動作は他のタイプに対して実装されていないことを示すために

例外NotImplementedError

[...]ユーザー定義の基本クラスでは、メソッドをオーバーライドするために派生クラスが必要な場合、またはクラスの開発中に実際の実装を追加する必要があることを示すために、抽象メソッドがこの例外を発生させる必要があります。

詳細については、リンクを参照してください。


13

1つの理由はパフォーマンスです。短時間で多くの操作を実行できるリッチ比較のような状況では、多くの例外の設定と処理は、単にNotImplemented値を返すよりもはるかに時間がかかる可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.