__ne__ 是否使用覆盖的 __eq__?

Does __ne__ use an overridden __eq__?

假设我有以下程序:

class A(object):                                                                                                                                                                                                                                                              
    def __eq__(self, other):
        return True

a0 = A() 
a1 = A() 
print a0 != a1

如果你 运行 它与 Python 输出是 True。我的问题是

  1. __ne__方法没有实现,Python是否属于默认方法?
  2. 如果Python落在一个判断两个对象是否相等的默认方法上,它不应该调用__eq__然后取反结果吗?

来自the docs

There are no implied relationships among the comparison operators. The truth of x==y does not imply that x!=y is false. Accordingly, when defining __eq__(), one should also define __ne__() so that the operators will behave as expected.

快速回答

[if] the __ne__ method is not implemented, does Python fall on a default one?

一般来说,是的,确实如此 - 但重点是:默认 __ne__ 的行为是什么。这取决于 Python 的版本(请继续阅读)。

if Python fall on a default method to determine whether two objects are equal or not, shouldn't it call __eq__ and then negate the result?

  • Python 2.x:没有。在 self != other 上,如果 selfother 未提供自定义 __ne__,则仅检查对象标识(因此有效行为等同于 self is not other)。
  • Python 3.x:的确,__ne__的默认实现调用了__eq__并对结果取反(但在技术层面上有一些微妙之处,请阅读上)。

插曲:当__ne__returnsNotImplemented

时会发生什么

Python的每一种“丰富比较”方法,包括__ne__,都可以或者给出一个果断的答案(通常:TrueFalse)我不知道!通过返回一个特殊的单例对象,NotImplemented (warning: not to be confused with NotImplementedError!) .

self != other 上,首先调用 self.__ne__(other),如果它 returns NotImplemented 然后 Python 尝试 other.__ne__(self)(但是,如果other 的类型是 self 类型的子类,但不是同一类型那么顺序是相反的:首先调用 other.__ne__(self),并且仅当 returns NotImplemented self.__ne__(other) 调用已尝试)。如果两个调用都返回 NotImplemented,则 Python 回退到基于对象身份的检查 (self is not other)。

==__eq__ 相关的行为是类似的。

这就是片段中 docs 所指的内容:

__eq__() and __ne__() are their own reflection

注意:这个片段应该理解为:__eq__()是自己的倒影__ne__() 是它自己的反映(每个都是独立的,单独的)。

Python 2.x 行为

正如 Ami Tavory 所写,当谈到标准行为和默认实现时,__ne____eq__ 之间没有隐含关系。

Python 3.x 行为

来自docs

For __ne__(), by default it delegates to __eq__() and inverts the result unless it is NotImplemented.

换句话说,object.__ne__ 的行为(大致)等同于:

def __ne__(self, other):
    res = self.__eq__(other)
    if res is NotImplemented:
        return NotImplemented
    return not res

当然,object.__ne__ 可以被子类提供的另一个实现覆盖。这就是为什么当你实现一个子类时,例如 dict,如果你想提供你自定义的 __eq__ 你还需要提供 __ne__(它的实现可以像以上代码片段,甚至更短:return object.__ne__(self, other)).