15

Take the following example:

>>> class C(object):
...     def __init__(self, p):
...         self.p = p
...     def __eq__(self, o):
...         return True
... 
>>> C(1) is C(2)
False
>>> C(1) == C(2)
True
>>> C(1) != C(2)
True # <- Why?!?

So now the two objects are equal and not-equal at the same time. I though the two operations are opposing?!

George Stocker
  • 57,289
  • 29
  • 176
  • 237
Emil Ivanov
  • 37,300
  • 12
  • 75
  • 90

3 Answers3

28

Python’s “Data model” explains it all:

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.

In C(1) != C(2), it’s using the default implementation, where objects are equal only to themselves and unequal to everything else.

Defining __cmp__ can be simpler, as it is used as a fallback for all comparison operations, not just some of them:

...   def __cmp__(self, o):
...     return 0
>>> C(1) != C(2)
False
Josh Lee
  • 171,072
  • 38
  • 269
  • 275
  • Is there any reason not to just override ```__cmp__``` over ```__eq__```? – Adam Parkin Mar 04 '16 at 18:56
  • 1
    `__cmp__` is an older Python feature (`__eq__` takes precedence) and has now been removed from Python 3 so really shouldn't be used in any Python code now: https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons – Cas Jun 11 '17 at 12:29
  • 1
    "That was true for Python 2, but in Python 3 that’s not good advice, because a useful default `__ne__` implementation is inherited from the object class, and it’s rarely necessary to override it." - Fluent Python – 0TTT0 Dec 24 '17 at 23:39
8

There is a separate function for != which is __ne__ which is implicitly defined to compare the instance members.

What you want to do is:

def __ne__(self, other):
    return not self.__eq__(other)

or some variant of this.

tzot
  • 92,761
  • 29
  • 141
  • 204
milkypostman
  • 2,955
  • 27
  • 23
2

You have to define both __ne__ and __eq__. And you probably ought to consider implementing __cmp__ too!

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490