【问题标题】: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 这就是为什么他们建议您同时定义“以便操作员按预期行事”
  • 据我所知,这两种方法是独立的,覆盖其中一个并不意味着覆盖另一个。
  • @oleg 查看我的最佳示例。覆盖__eq__确实隐式定义__ne__,至少在Python 3中是这样。
  • 看来如果你不定义__ne__它使用not__eq__。但x==y 的真相并不意味着x!=y 是假的。这就是为什么你应该定义两者。

标签: python operator-overloading equality inequality


【解决方案1】:

Python 3 更改了 == 案例的行为,请参阅 Python 3, What's New

!= 现在返回与== 相反的值,除非== 返回NotImplemented

它被认为是a useful change

文档没有更新确实是long standing bug

然而,正如对报告的评论指出的那样,如果您从已经定义了 __ne__ 的类继承,仅覆盖 __eq__ 是不够的,您还必须覆盖__ne__ 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-28
    • 2016-09-19
    • 2015-07-10
    • 2017-06-07
    • 1970-01-01
    • 2018-08-21
    • 2011-05-20
    • 1970-01-01
    相关资源
    最近更新 更多