为啥 Python 文档说我在定义 __eq__ 时需要定义 __ne__?
Posted
技术标签:
【中文标题】为啥 Python 文档说我在定义 __eq__ 时需要定义 __ne__?【英文标题】:Why do the Python docs say I need to define __ne__ when I define __eq__?为什么 Python 文档说我在定义 __eq__ 时需要定义 __ne__? 【发布时间】:2014-08-18 18:36:18 【问题描述】:根据Python docs:“在定义__eq__()
时,还应该定义__ne__()
,以便操作符按预期运行”。
但是,Python 似乎自动将__ne__
计算为not __eq__
:
In [8]: class Test:
def __eq__(self, other):
print("calling __eq__")
...: return isinstance(other, Test)
...:
In [9]: a = Test()
In [10]: b = Test()
In [11]: a == b
calling __eq__
Out[11]: True
In [12]: a != b
calling __eq__
Out[12]: False
In [13]: a == 1
calling __eq__
Out[13]: False
In [14]: a != 1
calling __eq__
Out[14]: True
那么定义__ne__
如果它只是return not self.__eq__(other)
又有什么意义呢?此外,这种行为实际记录在哪里?
编辑
显然,我使用 Python 3 很重要。在 Python 2 中,我得到了
In [1]: class Test(object):
...: def __eq__(self, other):
...: print("calling __eq__")
...: return isinstance(other, Test)
...:
In [2]: a = Test()
In [3]: b = Test()
In [4]: a == b
calling __eq__
Out[4]: True
In [5]: a != b
Out[5]: True
In [6]: a == 1
calling __eq__
Out[6]: False
In [7]: a != 1
Out[7]: True
但我引用的文档是 Python 3 文档。他们只是没有更新吗?
【问题讨论】:
作为猜测(因此不是答案),您可能想要定义一些东西,例如Rect() == Square() # True
, Square() == Rect() # False
这就是为什么他们建议您同时定义“以便操作员按预期行事”
Related question and a possible duplicate
据我所知,这两种方法是独立的,覆盖其中一个并不意味着覆盖另一个。
@oleg 查看我的最佳示例。覆盖__eq__
确实隐式定义__ne__
,至少在Python 3中是这样。
看来如果你不定义__ne__
它使用not
__eq__
。但x==y
的真相并不意味着x!=y
是假的。这就是为什么你应该定义两者。
【参考方案1】:
Python 3 更改了 ==
案例的行为,请参阅 Python 3, What's New:
!=
现在返回与==
相反的值,除非==
返回NotImplemented
。
它被认为是a useful change。
文档没有更新确实是long standing bug。
然而,正如对报告的评论指出的那样,如果您从已经定义了 __ne__
的类继承,仅覆盖 __eq__
是不够的,您还必须覆盖__ne__
方法。
【讨论】:
以上是关于为啥 Python 文档说我在定义 __eq__ 时需要定义 __ne__?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Python 有一个 __ne__ 运算符方法而不仅仅是 __eq__?
为啥 `if None.__eq__("a")` 似乎评估为 True(但不完全)?