If you don't need to be able to efficiently retrieve a canonical copy of an object given a different copy, you can just use a set:
s = set()
s.add(3)
s.add(3)
# s only has one 3 in it
If you do need to be able to efficiently retrieve canonical copies of objects, don't store them by the hash value - that'd be horribly broken. Just use the hashable directly.
class Interner(object):
def __init__(self):
self._store = {}
def canonical_object(self, thing):
"""Returns a canonical object equal to thing.
Always returns the same result for equal things.
"""
return self._store.setdefault(thing, thing)
With the weakref
module, you can improve this to not keep a canonical object if the client code lets go of it, just like the built-in intern
function does for strings.