__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
。我的问题是
__ne__
方法没有实现,Python是否属于默认方法?
- 如果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
上,如果 self
或 other
未提供自定义 __ne__
,则仅检查对象标识(因此有效行为等同于 self is not other
)。
- Python 3.x:的确,
__ne__
的默认实现调用了__eq__
并对结果取反(但在技术层面上有一些微妙之处,请阅读上)。
插曲:当__ne__
returnsNotImplemented
时会发生什么
Python的每一种“丰富比较”方法,包括__ne__
,都可以或者给出一个果断的答案(通常:True
或False
)或说我不知道!通过返回一个特殊的单例对象,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)
).
假设我有以下程序:
class A(object):
def __eq__(self, other):
return True
a0 = A()
a1 = A()
print a0 != a1
如果你 运行 它与 Python 输出是 True
。我的问题是
__ne__
方法没有实现,Python是否属于默认方法?- 如果Python落在一个判断两个对象是否相等的默认方法上,它不应该调用
__eq__
然后取反结果吗?
来自the docs:
There are no implied relationships among the comparison operators. The truth of
x==y
does not imply thatx!=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
上,如果self
或other
未提供自定义__ne__
,则仅检查对象标识(因此有效行为等同于self is not other
)。 - Python 3.x:的确,
__ne__
的默认实现调用了__eq__
并对结果取反(但在技术层面上有一些微妙之处,请阅读上)。
插曲:当__ne__
returnsNotImplemented
时会发生什么
Python的每一种“丰富比较”方法,包括__ne__
,都可以或者给出一个果断的答案(通常:True
或False
)或说我不知道!通过返回一个特殊的单例对象,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 isNotImplemented
.
换句话说,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)
).