Emil Ivanov
Emil Ivanov

Reputation: 37673

Why does Python's != operator think that arguments are equal and not equal at the same time?

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?!

Upvotes: 15

Views: 5096

Answers (3)

milkypostman
milkypostman

Reputation: 3043

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.

Upvotes: 8

Josh Lee
Josh Lee

Reputation: 177895

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

Upvotes: 28

David Heffernan
David Heffernan

Reputation: 613592

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

Upvotes: 2

Related Questions