darrienkennedy
darrienkennedy

Reputation: 88

Comparing two objects using __dict__

Is there ever a reason not to do this to compare two objects:

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

as opposed to checking each individual attribute:

def __eq__(self, other):
    return self.get_a() == other.get_a() and self.get_b() == other.get_b() and ...

Initially I had the latter, but figured the former was the cleaner solution.

Upvotes: 2

Views: 1303

Answers (2)

chepner
chepner

Reputation: 531125

You can be explicit and concise:

def __eq__(self, other):
    fetcher = operator.attrgetter("a", "b", "c", "d")
    try:
        return self is other or fetcher(self) == fetcher(other)
    except AttributeError:
        return False

Just comparing the __dict__ attribute (which might not exist if __slots__ is used) leaves you open to the risk that an unexpected attribute exists on the object:

class A:
    def __init__(self, a):
        self.a = a
    def __eq__(self, other):
        return self.__dict__ == other.__dict__

a1 = A(5)
a2 = A(5)
a1.b = 3
assert a1 == a2  # Fails

Upvotes: 4

timgeb
timgeb

Reputation: 78690

Some comments:

You should include a self is other check, otherwise, under certain conditions, the same object in memory can compare unequal to itself. Here is a demonstration. The instance-check chrisz mentioned in the comments is a good idea as well.

The dicts of self and other probably contain many more items than the attributes you are manually checking for in the second version. Therefore, the first one will be slower.

(Lastly, but not related to the question, we don't write getters and setters in Python. Access attributes directly with the dot-notation, and if something special needs to happen when getting/setting an attribute, use a property.)

Upvotes: 0

Related Questions