web-dev-qa-db-ja.com

__eq__は、Pythonで、どのような順序で処理されますか?

Pythonは比較演算子の左/右バージョンを提供していないため、どの関数を呼び出すかをどのように決定しますか?

class A(object):
    def __eq__(self, other):
        print "A __eq__ called"
        return self.value == other
class B(object):
    def __eq__(self, other):
        print "B __eq__ called"
        return self.value == other

>>> a = A()
>>> a.value = 3
>>> b = B()
>>> b.value = 4
>>> a == b
"A __eq__ called"
"B __eq__ called"
False

これは両方を呼び出すようです__eq__ 機能。公式の決定木を探しているだけです。

73
PyProg

a == b式は、存在するため、A.__eq__を呼び出します。そのコードにはself.value == otherが含まれます。 intは自身をBと比較する方法を知らないため、PythonはB.__eq__を呼び出して、それをintと比較する方法を知っているかどうかを確認します。

比較する値を示すためにコードを修正する場合:

class A(object):
    def __eq__(self, other):
        print("A __eq__ called: %r == %r ?" % (self, other))
        return self.value == other
class B(object):
    def __eq__(self, other):
        print("B __eq__ called: %r == %r ?" % (self, other))
        return self.value == other

a = A()
a.value = 3
b = B()
b.value = 4
a == b

印刷されます:

A __eq__ called: <__main__.A object at 0x013BA070> == <__main__.B object at 0x013BA090> ?
B __eq__ called: <__main__.B object at 0x013BA090> == 3 ?
92
Ned Batchelder

Python2.xはa == bを検出すると、次のことを試みます。

  • type(b)が新しいスタイルのクラスで、type(b)type(a)のサブクラスであり、type(b)__eq__をオーバーライドした場合、結果b.__eq__(a)です。
  • type(a)__eq__をオーバーライドした場合(つまり、type(a).__eq__object.__eq__ではない場合)、結果はa.__eq__(b)になります。
  • type(b)__eq__をオーバーライドした場合、結果はb.__eq__(a)になります。
  • 上記のいずれにも当てはまらない場合、Pythonは__cmp__を探すプロセスを繰り返します。存在する場合、オブジェクトは、zeroを返す場合に等しいです。
  • 最終フォールバックとして、Pythonはobject.__eq__(a, b)を呼び出します。これは、Trueaが同じオブジェクトである場合、bです。

特別なメソッドのいずれかがNotImplementedを返す場合、Pythonはメソッドが存在しないかのように動作します。

最後のステップに注意してください。ab==をオーバーロードしない場合、a == ba is bと同じです。


から https://eev.ee/blog/2012/03/24/python-faq-equality/

55
kev