When writing custom classes it is often important to allow equivalence by means of the ==
and !=
operators. In Python, this is made possible by implementing the __eq__
and __ne__
special methods, respectively. The easiest way I've found to do this is the following method:
class Foo:
def __init__(self, item):
self.item = item
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.__dict__ == other.__dict__
else:
return False
def __ne__(self, other):
return not self.__eq__(other)
Do you know of more elegant means of doing this? Do you know of any particular disadvantages to using the above method of comparing __dict__
s?
Note: A bit of clarification--when __eq__
and __ne__
are undefined, you'll find this behavior:
>>> a = Foo(1)
>>> b = Foo(1)
>>> a is b
False
>>> a == b
False
That is, a == b
evaluates to False
because it really runs a is b
, a test of identity (i.e., "Is a
the same object as b
?").
When __eq__
and __ne__
are defined, you'll find this behavior (which is the one we're after):
>>> a = Foo(1)
>>> b = Foo(1)
>>> a is b
False
>>> a == b
True
The 'is' test will test for identity using the builtin 'id()' function which essentially returns the memory address of the object and therefore isn't overloadable.
However in the case of testing the equality of a class you probably want to be a little bit more strict about your tests and only compare the data attributes in your class:
This code will only compare non function data members of your class as well as skipping anything private which is generally what you want. In the case of Plain Old Python Objects I have a base class which implements __init__, __str__, __repr__ and __eq__ so my POPO objects don't carry the burden of all that extra (and in most cases identical) logic.
The way you describe is the way I've always done it. Since it's totally generic, you can always break that functionality out into a mixin class and inherit it in classes where you want that functionality.
You don't have to override both
__eq__
and__ne__
you can override only__cmp__
but this will make an implication on the result of ==, !==, < , > and so on.is
tests for object identity. This means ais
b will beTrue
in the case when a and b both hold the reference to the same object. In python you always hold a reference to an object in a variable not the actual object, so essentially for a is b to be true the objects in them should be located in the same memory location. How and most importantly why would you go about overriding this behaviour?Edit: I didn't know
__cmp__
was removed from python 3 so avoid it.You need to be careful with inheritance:
Check types more strictly, like this:
Besides that, your approach will work fine, that's what special methods are there for.
From this answer: https://stackoverflow.com/a/30676267/541136 I have demonstrated that, while it's correct to define
__ne__
in terms__eq__
- instead ofyou should use:
I think that the two terms you're looking for are equality (==) and identity (is). For example: