1

私の設計は完全に狂っているかもしれませんが、比較可能な2つの派生クラスオブジェクトがある場合、クラスD1は基本的に常に>クラスD2になります。(Ivy Bridge と 286 を比較するとします)。isinstance(D2) を使用せずにクラス D1 の比較を実装してそれを反映するにはどうすればよいですか?

私はこれを見ました: Comparing two objectsPython でのダックタイピングの場合、isinstance をテストする必要がありますか?

「type」属性を追加してタイプを比較することもできますが、その場合は isinstance を使用することもできます。最も簡単な方法は isinstance を使用することです...もっと良い提案はありますか?

4

2 に答える 2

2

私は、「D2 が常に D1 よりも大きいのはなぜですか?」と自問します。言い換えれば、それらには、比較の基にすることが理にかなっている共通の属性がありますか。この質問に対する適切な答えがない場合は、これら 2 つのオブジェクトの比較を作成することが実際に意味があるかどうかを尋ねる価値があるかもしれません。

これらのことを考慮した後でも、比較を行うのは良い考えだと思う場合は、 を使用してisinstanceください。それが言語にまだ存在するのには理由があります-そして、Pythonは常に悪いことでisinstanceはないことを意味する悪い習慣と見なされるものを常に非推奨にしています。

問題は、 isinstance を使用して不必要に型チェックを行う場合です。言い換えれば、ユーザーは完全に不必要な「飛躍する前に見てください」コンテキストでそれを使用することがよくあります。

if not isinstance(arg,Foo): 
   raise ValueError("I want a Foo")

この場合、ユーザーが Foo によく似たものを関数に入れないと、とにかく例外が発生します。なぜ Foo オブジェクトのみに制限するのですか? ただし、あなたの場合、概念的な観点からは、オブジェクトのタイプが実際に重要であるように見えます。これが存在する理由ですisinstance(私の意見では)。

于 2012-07-14T03:57:47.750 に答える
1

私はこのようなことをします:

class D1(object):
   def __val_cmp(self, other):
      # compare by attributes here
      if self.attr < other.attr:
         return -1
      elif self.attr > other.attr:
         return 1
      return 0

   def __cmp__(self, other):
      greater = isinstance(other, type(self))
      lesser = isinstance(self, type(other))
      if greater and lesser:
         # same type so compare by attributes
         return self.__val_cmp(other)
      elif greater:
         return 1
      elif lesser:
         return -1
      else:
         # other type is not a parent or child type, so just compare by attributes
         return self.__val_cmp(other)
  • D2 が D1 のサブタイプである場合、D2 のインスタンスは常に D1 のインスタンスより少ない比較を行います。
  • D0 が D1 の親型である場合、D0 のインスタンスは常に D1 のインスタンスよりも大きくなります。
  • D1 のインスタンスを D1 の別のインスタンスと比較する場合、比較はクラスの属性によって行われます。
  • D1 のインスタンスを未知のクラスのインスタンスと比較する場合、比較はクラスの属性によって行われます
于 2012-07-14T03:57:40.577 に答える