You may just override __eq__
method of the object. When you are just comparing objects only identities are compared (they are not the same object, thus ==
will result in False
):
User-defined classes have __eq__()
and __hash__()
methods by default; with them, all objects compare unequal (except with themselves) and x.__hash__()
returns id(x)
Here's a small example:
>>> class A(object):
... def __init__(self, i):
... self.i = i
...
>>>
>>> a = A(1)
>>> b = A(1)
>>> c = A(2)
>>> a == b
False
>>> a == c
False
But if you override comparison you'll get what you need:
>>> class B(object):
... def __init__(self,i):
... self.i = i
... def __eq__(self,o):
... return self.i == o.i
... def __ne__(self,o):
... return self.i != o.i
...
>>> d = B(1)
>>> e = B(1)
>>> f = B(2)
>>> d == e
True
>>> d == f
False
>>>
Also comparing directories does "deep comparison" (so you can compare dictionaries directly):
>>> d1 = {1:2, 3:4}
>>> d2 = {}
>>> d2[1] = 2
>>> d2[3] = 4
>>> d3 = {5:6, 3:4}
>>> d1 == d2
True
>>> d1 == d3
False
Also note that there are some rules[1][2] that you should follow when implementing rich comparison methods, for example:
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.
Arguments to rich comparison methods are never coerced.
A class that overrides __eq__()
and does not define __hash__()
will have its __hash__()
implicitly set to None
.
Requested update:
Arguments are never coerced (coercion in python glossary) means that checking input argument (o
in my example) is your responsibility, try:
>>> d == 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __eq__
AttributeError: 'int' object has no attribute 'i'
And it's even possible to compare objects of different classes:
>>> d == a
True
And about __hash__
being set to None
means, that hash(obj)
fails:
>>> hash(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'B'
And every collection requiring hashing also fails:
>>> set((d,))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'B'
While it works with A
:
>>> set((a,))
{<__main__.A object at 0x7f8a85fe4668>}