19

objオブジェクトを使用してアクションを実行できるかどうかを判断するさまざまなアプローチ間のトレードオフを理解しようとしていますdo_stuff()。私が理解しているように、これが可能かどうかを判断するには3つの方法があります。

# Way 1
if isinstance(obj, Foo):
    obj.do_stuff()

# Way 2
if hasattr(obj, 'do_stuff'):
    obj.do_stuff()

# Way 3
try:
    obj.do_stuff()
except:
    print 'Do something else'

推奨される方法 (およびその理由) はどれですか?

4

3 に答える 3

12

Python コミュニティで教えられているモットーである「許可よりも許しを求める方が簡単」(EAFP)のため、Python コーダーは一般的に最後の方法を好んでいると思います。

一言で言えば、モットーは、何かをする前に何かをすることができるかどうかを確認しないことを意味します。代わりに、操作を実行してください。失敗した場合は適切に対処してください。

また、3 番目の方法には、操作が機能することが明確になるという追加の利点があります。


そうは言っても、exceptそのような裸の使用は本当に避けるべきです. そうすることで、関係のないものであっても、すべての例外をキャプチャできます。代わりに、例外を具体的にキャプチャすることをお勧めします。

ここでは、次のようにキャプチャしますAttributeError

try:
    obj.do_stuff()   # Try to invoke do_stuff
except AttributeError:
    print 'Do something else'  # If unsuccessful, do something else
于 2014-01-09T15:57:16.123 に答える
7

ダックタイピングisinstanceを使用するという Python の規則に反するランでのチェック。

hasattr正常に動作しますが、Pythonic EAFPの代わりにLook Before you Leapです。

方法 3 の実装は危険do_stuffです。メソッドによって発生したエラーを含め、ありとあらゆるエラーをキャッチするからです。あなたはより正確に行くことができます:

try:
    _ds = obj.do_stuff
except AttributeError:
    print('Do something else')
else:
    _ds()

しかし、この場合、わずかなオーバーヘッドにもかかわらず、私は方法 2 を好みます。

于 2014-01-09T16:00:07.037 に答える
4

正解は「どちらでもない」というものです。hasattr は機能を提供しませんが、おそらくすべてのオプションの中で最悪です。

動作するため、Python のオブジェクト指向の性質を使用します。OO 分析は決して正確ではなく、しばしば混乱を招きますが、私たちはクラス階層を使用しています。人々はオブジェクトを把握し、優れたオブジェクト モデルは、コーダーが物事をより迅速に、より少ないエラーで変更するのに役立ちます。適切なコードが適切な場所にクラスター化されます。オブジェクト:

  • どの実装が存在するかを考慮せずにそのまま使用できます
  • 何をどこで変更する必要があるかを明確にする
  • 一部の機能への変更を他の機能への変更から分離します。Y を壊すことを恐れずに X を修正できます。

hasattr と isinstance

isinstance または hasattr をまったく使用しなければならないということは、オブジェクト モデルが壊れているか、間違って使用していることを示しています。正しいことは、オブジェクト モデルを修正するか、使用方法を変更することです。これら 2 つの構成要素は同じ効果を持ち、「これを行うにはコードが必要です」という命令的な意味で、それらは同等です。構造的に大きな違いがあります。このメソッドに初めて出会ったとき (または他のことを数か月行った後)、isinstance は、実際に何が起こっているのか、他に何が可能なのかについて、より多くの情報を伝えます。Hasattr は何も「教えて」くれません。

開発の長い歴史により、私たちは FORTRAN や「自分は誰ですか」スイッチがたくさんあるコードから遠ざかりました。オブジェクトを使用することを選択したのは、オブジェクトがコードの操作を容易にするのに役立つことがわかっているからです。hasattr を選択すると機能が提供されますが、何も修正されず、コードは開始前よりも壊れています。将来この機能を追加または変更する場合、不均等にグループ化され、少なくとも 2 つの編成原則を持つコードを処理する必要があります。その一部は「あるべき」場所にあり、残りは他の場所にランダムに散らばっています。まとまるようなものはありません。これは 1 つのバグではなく、hasattr を通過する実行パスに点在する潜在的なミスの地雷原です。

したがって、選択肢がある場合、順序は次のとおりです。

  1. オブジェクト モデルを使用するか、それを修正するか、少なくとも問題点と修正方法を突き止めます。
  2. インスタンスを使用
  3. hasattr を使用しないでください
于 2016-04-07T14:00:02.063 に答える