__eq__ 在 Python 中是如何处理的以及以什么顺序处理?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3588776/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:51:42  来源:igfitidea点击:

How is __eq__ handled in Python and in what order?

pythoncomparisonuser-defined

提问by PyProg

Since Python does not provide left/right versions of its comparison operators, how does it decide which function to call?

由于 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

This seems to call both __eq__functions. Just looking for the official decision tree.

这似乎调用了这两个__eq__函数。只是在寻找官方的决策树。

采纳答案by Ned Batchelder

The a == bexpression invokes A.__eq__, since it exists. Its code includes self.value == other. Since int's don't know how to compare themselves to B's, Python tries invoking B.__eq__to see if it knows how to compare itself to an int.

a == b表达调用A.__eq__,因为它的存在。它的代码包括self.value == other. 由于 int 不知道如何将自己与 B 进行比较,因此 Python 尝试调用B.__eq__以查看它是否知道如何将自己与 int 进行比较。

If you amend your code to show what values are being compared:

如果您修改代码以显示正在比较的值:

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

it will print:

它会打印:

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

回答by kev

When Python2.x sees a == b, it tries the following.

当 Python2.x 看到 时a == b,它会尝试以下操作。

  • If type(b)is a new-style class, and type(b)is a subclass of type(a), and type(b)has overridden __eq__, then the result is b.__eq__(a).
  • If type(a)has overridden __eq__(that is, type(a).__eq__isn't object.__eq__), then the result is a.__eq__(b).
  • If type(b)has overridden __eq__, then the result is b.__eq__(a).
  • If none of the above are the case, Python repeats the process looking for __cmp__. If it exists, the objects are equal iff it returns zero.
  • As a final fallback, Python calls object.__eq__(a, b), which is Trueiff aand bare the same object.
  • 如果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),它是Trueiffa并且b是同一个对象。

If any of the special methods return NotImplemented, Python acts as though the method didn't exist.

如果任何特殊方法 return NotImplemented,Python 就好像该方法不存在一样。

Note that last step carefully: if neither anor boverloads ==, then a == bis the same as a is b.

请注意最后一步:如果既不是a也不是b重载==,则a == b与 相同a is b



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

来自https://eev.ee/blog/2012/03/24/python-faq-equality/