Search code examples
pythonobjectdeepequals

How to do a deepequals on a object in python


Is there a function so that I can do

class Test():
    def __init__(self):
        self.value_1 = 42

x = Test()
y = Test()
deepequals(x, y) == True
x.value = 7
deepequals(x, y) == False
y.value = 7
deepequals(x, y) == True

However, by default, it would always be false because x and y are different instances of Test


Solution

  • You can implement the __eq__ (equals) "magic method":

    class Test():
        def __init__(self):
            self.value_1 = 42
        def __eq__(self, other):
            return self.__dict__ == other.__dict__
    

    where __dict__ holds all of the instance attributes. This will return True when two objects have all the same values for all the same attributes. This gives the result you want:

    >>> x = Test()
    >>> y = Test()
    >>> x == y
    True
    >>> x.value = 7
    >>> x == y
    False
    >>> y.value = 7
    >>> x == y
    True
    

    To support comparisons with objects that do not have a __dict__ attribute (like those defined in C or using __slots__ instead) you can either check for that attribute first using hasattr:

    return hasattr(other, '__dict__') and self.__dict__ == other.__dict__
    

    or access it safely using getattr with a default:

    return self.__dict__ == getattr(other, '__dict__', None)