Compare object instances for equality by their attributes in Python

0 votes
asked Aug 4, 2009 by %c5%bdeljko-%c5%bdiv

What is the best way to compare two instances of some object for equality in Python? I'd like to be able to do something like

Example:

doc1 = ErrorDocument(path='/folder',title='Page')
doc2 = ErrorDocument(path='/folder',title='Page')

if doc1 == doc2: # this should be True
    #do something

EDIT:

To further clarify the question. I'd like to compare by attribute values, and to make a more generic solution than

def __eq__(self, other):
    return self.path == other.path and self.title == other.title

Should the __eq__() method look something like this?

def __eq__(self, other):
    # Is the other instance of the same object
    # Loop through __dict__ and compare values to attributes of other

7 Answers

0 votes
answered Jan 4, 2009 by asb

Instance of a class when compared with == comes to non-equal. The best way is to ass the cmp function to your class which will do the stuff.

If you want to do comparison by the content you can simply use cmp(obj1,obj2)

In your case cmp(doc1,doc2) It will return -1 if the content wise they are same.

0 votes
answered Aug 4, 2009 by silfverstrom

When comparing instances of objects, the __cmp__ function is called.

If the == operator is not working for you by default, you can always redefine the __cmp__ function for the object.

Edit:

As has been pointed out, the __cmp__ function is deprecated since 3.0. Instead you should use the “rich comparison” methods.

0 votes
answered Aug 4, 2009 by kiv

Implement the __eq__ method in your class; something like this:

def __eq__(self, other):
    return self.path == other.path and self.title == other.title

Edit: if you want your objects to compare equal if and only if they have equal instance dictionaries:

def __eq__(self, other):
    return self.__dict__ == other.__dict__
0 votes
answered Aug 4, 2009 by christopher

You override the rich comparison operators in your object.

class MyClass:
 def __lt__(self, other):
      # return comparison
 def __le__(self, other)
      # return comparison
 def __eq__(self, other)
      # return comparison
 def __ne__(self, other)
      # return comparison
 def __gt__(self, other)
      # return comparison
 def __ge__(self, other)
      # return comparison
0 votes
answered Aug 4, 2009 by e-satis

As usual with Python, it's KISS:

class Test(object):

    def __init__(self, attr1, attr2):
        self.attr1 = attr1
        self.attr2 = attr2

    def __str__(self):
        return str(self.__dict__)

    def __eq__(self, other): 
        return self.__dict__ == other.__dict__

t1 = Test("foo", 42)
t2 = Test("foo", 42)
t3 = Test("bar", 42)

print t1, t2, t3
print t1 == t2
print t2 == t3

It outputs:

{'attr2': 42, 'attr1': 'foo'} {'attr2': 42, 'attr1': 'foo'} {'attr2': 42, 'attr1': 'bar'}
True
False

N.B.: be aware that before Python 3.0, you are more likely to use __cmp__ instead of __eq__, working the same way.

0 votes
answered Jan 11, 2013 by user2215595

I tried the initial example (see 7 above) and it did not work in ipython. Note that cmp(obj1,obj2) returns a "1" when implemented using two identical object instances. Oddly enough when I modify one of the attribute values and recompare, using cmp(obj1,obj2) the object continues to return a "1". (sigh...)

Ok, so what you need to do is iterate two objects and compare each attribute using the == sign.

0 votes
answered Aug 26, 2016 by fievel

As a summary :

  1. It's advised to implement __eq__ rather than __cmp__, except if you run python <= 2.0 (__eq__ has been added in 2.1)
  2. Don't forget to also implement __ne__ (should be something like return not self.__eq__(other) or return not self == other except very special case)
  3. Don`t forget that the operator must be implemented in each custom class you want to compare (see example below).
  4. If you want to compare with object that can be None, you must implement it. The interpreter cannot guess it ... (see example below)

    class B(object):
      def __init__(self):
        self.name = "toto"
      def __eq__(self, other):
        if other is None:
          return False
        return self.name == other.name
    
    class A(object):
      def __init__(self):
        self.toto = "titi"
        self.b_inst = B()
      def __eq__(self, other):
        if other is None:
          return False
        return (self.toto, self.b_inst) == (other.toto, other.b_inst)
    
Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...