I want set/dict to treat the objects of the same type as the single object, so there won't be more than one object of the same type in the set/dict.
I also want these objects to be comparable in non-trivial way, for instance against their internal state: C(value=1) == C(value=2) must return False and C(value=1) == C(value=1) must return True.
The naïve approach failed:
class Base(object):
KEY = 'base'
def __init__(self, value):
self.value = value
def __hash__(self):
# hash is the same for all objects of the same type
return hash(type(self).KEY)
def __eq__(self, other):
# objects are compared against `.value` attribute
return bool(self.value == other.value)
def __repr__(self):
return '{}({})'.format(type(self).__name__, self.value)
class Derived(Base):
KEY = 'derived'
print {Base(1), Base(2), Derived(3), Derived(4)}
# actual: set([Base(1), Base(2), Derived(3), Derived(4)])
# desired: set([Base(?), Derived(?)]) -- "?" for arbitrary value
print {Base(1): 1, Base(2): 2}
# actual: {Base(1): 1, Base(2): 2}
# desired: {Base(?): ?} -- "?" for arbitrary value
Is is it possible to store objects of user-defined class in the set/dict in a such way that there will be no more than one object in set/dict with the same class, but keep these objects still non-trivial comparable?
I know that I can store objects in dict using type as a key:
d = {
Base: Base(1),
Derived: Derived(2),
}
but this way does not solve the issue with set/frozenset.
b1 = Base(1)andb2 = Base(2), and they are added to set:s = {b1, b2}, then both outcomesset([b1])andset([b2])will be valid and desirable.