__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
How is __eq__ handled in Python and in what order?
提问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, andtype(b)is a subclass oftype(a), andtype(b)has overridden__eq__, then the result isb.__eq__(a). - If
type(a)has overridden__eq__(that is,type(a).__eq__isn'tobject.__eq__), then the result isa.__eq__(b). - If
type(b)has overridden__eq__, then the result isb.__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 returnszero. - As a final fallback, Python calls
object.__eq__(a, b), which isTrueiffaandbare 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。

