1

I want to define a hashable class with mutable fields, but if I define the __eq__ method myself (which definitely I want to do), it is no longer hashable by default and I need to define __hash__ method as well.

If I define the __hash__ method such that it just compares the id() values like it (I think) did by default before I defined __eq__ I get weird results.

According to this question, I have to define __eq__ the same way as __hash__ but I would like to understand why this is the case and, if possible, how to work around that.

To be specific, I want to define objects with two mutable fields containing integers:

class CustomObj:
    def __init__(self, a, b):
        self.a = a
        self.b = b

ObjA = CustomObj(1, 2)
ObjB = CustomObj(1, 2)

I want to be able to compare them to each other ObjA == ObjB, as well as to simple tuples ObjA == (1, 2). I also want to be able to store them in a set myset = set(), so that I can check both (1, 2) in myset and ObjA in myset for the same result. How can I achieve this?

This is my code at the moment, but it's definitely not behaving correctly:

class Agent:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __eq__(self, other):
        try:
            # Try comparing two agents
            return (self.x == other.x and self.y == other.y
                        and isinstance(other, Agent))
        except AttributeError:
            # If it fails, compare an agent and a tuple
            if isinstance(other, tuple) and len(other) == 2:
                return self.x == other[0] and self.y == other[1]
            else:
                return NotImplemented

    def __hash__(self):
        return id(self)

0 Answers0