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. – Alex Sidorov