Question

I have my own class

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

I need to make working in, for example this should return true:

    s = set()
    s.add(Point(5,5))
    b = Point(5,5)
    print(b in s)
Was it helpful?

Solution

You don't override in specifically, you make your type hashable in the right way and many capabilities (including but not limited to set.__contains__) start to work. When you just want to consider equality over a set of attributes, the easiest way is to delegate to tuples:

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

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def __hash__(self):
        return hash((self.x, self.y))

Note however that you can't sensibly mutate a Point once it's been inserted. Because mutation changes the hash value (according to this new definition of __hash__), you "lose access" to prior values, and basically leak them:

p = Point(1, 2)
s = {p}
p.x = 3
assert p not in s
# ... even though ...
assert list(s)[0] == p

Even more insidious: Sometimes it might work by chance, due to hash collisions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top