0

名、ミドルネーム、姓の属性を持つ Person クラスがあるとします。Person オブジェクトに対して 2 つの異なるタイプの等価性チェックを実行できるようにしたいと考えています。

  • すべての属性の文字列比較に基づいて正確に等しい
  • 矛盾していない、つまり "G. Bluth" == "George Oscar Bluth"

__eq__私はこれのためにand を__ne__別々に使用するというアイデアをいじっています:

Person('g', '', 'bluth') == Person('george', 'oscar', 'bluth')  # False
Person('g', '', 'bluth') != Person('george', 'oscar', 'bluth')  # False

それはきちんとした解決策のように思えますが、!=常に逆を返すとは限らないので、==私は緊張します. それは悪い習慣と見なされますか?演算子の使用を避けて、次のようなメソッドを使用する必要がありconsistent(self, other)ますか?

実装例:

class Person(object):
    def __init__(self, first, middle, last):
        self.first = first
        self.middle = middle
        self.last = last
    def __eq__(self, other):
        if type(other) is type(self):
            return self.__dict__ == other.__dict__
        return NotImplemented
    def __ne__(self, other):
        if type(other) is type(self):
            return not (self._compatible(self.first, other.first) and 
                        self._compatible(self.middle, other.middle) and 
                        self._compatible(self.last, other.last))
        return NotImplemented
    def _compatible(self, s, o):
        if s and o:
            if s == o or (len(s) == 1 and s == o[0]) or (len(o) == 1 and o == s[0]):
                return True
            return False
        return True
4

1 に答える 1

5

最小の驚きの原則: 不正確な一致を、オーバーロードされた演算子ではなく、名前付きメソッドにします。完全一致のオーバーロード==は問題ありませんが、明白でないセマンティクスで演算子をオーバーロードすると、混乱が生じる可能性があります。あと何文字か入力して書くのはすごく大変Person("G. Bluth").could_be(Person("George Oscar Bluth"))ですか?

于 2013-06-20T17:15:47.383 に答える