14

According to the Python docs: "when defining __eq__(), one should also define __ne__() so that the operators will behave as expected".

However, it appears that Python computes __ne__ as not __eq__ automatically:

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

So what's the point of defining __ne__ if it's just going to be return not self.__eq__(other)? And furthermore, where is this behavior actually documented?

EDIT

Apparently it matters that I am using Python 3. In Python 2, I get

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

But the docs I referenced are the Python 3 docs. Were they just not updated?

Marcellinov
  • 311
  • 7
  • 18
asmeurer
  • 86,894
  • 26
  • 169
  • 240
  • As a guess (and as such not an answer), you might want to define something e.g. `Rect() == Square() # True`, `Square() == Rect() # False` which is why they suggest you define both "so that the operators will behave as expected" – Adam Smith Jun 27 '14 at 15:29
  • 3
    [Related question and a possible duplicate](http://stackoverflow.com/questions/4352244/python-implementing-ne-operator-based-on-eq) – vaultah Jun 27 '14 at 15:29
  • as far as I know these two methods are independent and overriding one of them doesn't mean overriding of other. – oleg Jun 27 '14 at 15:29
  • @frostnational that question (and none of its answers) seem to mention this behavior of Python 3 – asmeurer Jun 27 '14 at 15:39
  • 1
    @oleg see my top example. Overriding `__eq__` *does* implicitly define `__ne__`, at least in Python 3. – asmeurer Jun 27 '14 at 15:39
  • 2
    It seems that if you do not define `__ne__` it uses `not` `__eq__`. But The truth of `x==y` does not imply that `x!=y` is false. That's why you should define both. – yoopoo Jun 27 '14 at 15:43

1 Answers1

16

Python 3 changed behaviour for the == case, see Python 3, What's New:

!= now returns the opposite of ==, unless == returns NotImplemented.

It was deemed a useful change.

The fact that the documentation has not been updated is indeed a long standing bug.

However, as a comment on the report points out, if you inherit from a class that already has defined __ne__, overriding just __eq__ is not enough and you'll also have to override the __ne__ method.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343