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.