ここでは主にPythonについて話していますが、これはおそらくほとんどの言語に当てはまると思います。可変オブジェクトがある場合、インプレース操作でオブジェクトも返すようにするのは悪い考えですか?ほとんどの例では、オブジェクトを変更してを返すだけのようNone
です。たとえば、list.sort
。
4 に答える
はい、それは悪い考えです。その理由は、インプレース操作と非インプレース操作の出力が明らかに同一である場合、プログラマーは頻繁にインプレース操作と非インプレース操作 ( List.sort()
vs. sorted()
) を混同し、検出が困難になるためです。エラー。
自分自身を返すインプレース操作により、「メソッドチェーン」を実行できますが、チェーンの途中で誤って副作用のある関数を埋めてしまう可能性があるため、これは悪い習慣です。
このようなエラーを防ぐには、メソッド チェーンに副作用のあるメソッドを 1 つだけ含める必要があり、その関数はチェーンの最後に配置する必要があります。チェーン内のその前の関数は、副作用なしで入力を変換する必要があります (たとえば、ツリーの移動、文字列のスライスなど)。インプレース操作がそれ自体を返す場合、プログラマーは、コピーを返す代替関数の代わりに誤ってそれを使用することになります。したがって、デバッグが困難なエラーを引き起こす可能性のある副作用 (List.sort()
対) はありません。sorted()
これが、Python 標準ライブラリ関数が常にコピーを返すか、オブジェクトをインプレースで返しNone
て変更するが、オブジェクトをインプレースで変更してそれ自体を返すことはない理由です。Django などの他の Python ライブラリもこの慣行に従います ( Django に関するこの非常によく似た質問を参照してください)。
オブジェクトを変更したメソッドから変更されたオブジェクトを返すことには、いくつかの利点がありますが、Python では推奨されません。self
変更操作の後に戻ると、オブジェクトでメソッドチェーンを実行できます。これは、同じオブジェクトで複数のメソッドを実行する便利な方法です。これは、オブジェクト指向プログラミングで非常に一般的なイディオムです。また、メソッド チェーンにより、流暢なインターフェースを簡単に実装できます。また、一部の関数型プログラミングのイディオムをより簡単に表現できます。
いくつかの例を挙げると、Python では、Mokaライブラリはメソッド チェーンを使用します。Java では、StringBuilder
クラスappend()
は同じオブジェクトに対する複数の呼び出しを許可します。JavaScript では、JQuery はメソッド チェーンを広範囲に使用します。Smalltalk はこの考えを次のレベルに引き上げます。デフォルトでは、特に指定しない限り、すべてのメソッドが返されます (したがって、メソッド チェーンが推奨されます)。これを、デフォルトで返される Python と比較してください。self
None
このイディオムの使用は Python では一般的ではありません。なぜなら、Python はCommand/Query Separation Principleに従っているためです。この原則では、「すべてのメソッドは、アクションを実行するコマンドか、呼び出し元にデータを返すクエリのいずれかである必要がありますが、そうではありません。両方"。
最後に戻るのが良いか悪いかself
は、個人の好みと混ざり合ったプログラミングの文化と慣習の問題です。上で述べたように、プログラミング言語の中にはこれを推奨するもの (Smalltalk など) もあれば、推奨しないもの (Python など) もあります。それぞれの視点には長所と短所があり、白熱した議論が繰り広げられます。あなたが著書通りの Pythonist である場合は、戻るのを控えたほうがよいでしょう。ただし、self
この規則を破ると便利な場合があることに注意してください。
ユースケースにもよると思います。インプレース操作からオブジェクトを返すことが害を及ぼす理由はわかりませんが、結果を使用しない可能性がありますが、純粋な機能主義に非常に気を配っていなければ、それは実際には問題ではありません。jQueryが使用するようなコールチェーンパターンが好きなので、関数が操作したオブジェクトを返すときに、さらに使用したい場合に備えて感謝しています。