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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.