I have created the following class, made to manage all instances created and to enable fast lookup and retrieval of specific values by the specified lookup keys: class InstanceManager[InstanceT, LookupT: Hashable](): def __init__( self, get_lookups: Callable[[InstanceT], Iterable[LookupT]], on_add: Opt[Callable[[InstanceT], None]] = None, on_remove: Opt[Callable[[InstanceT], None]] = None ) -> None: self._on_add = on_add self._on_remove = on_remove self._get_lookups = get_lookups self._all: list[InstanceT] = [] self._lookup: dict[LookupT, InstanceT] = {} self._LOCK = threading.RLock() def lookup(self, lookup: LookupT) -> InstanceT: return self._lookup[lookup] # atomic operation def all_instances(self) -> list[InstanceT]: with self._LOCK: return list(self._all) def get_lookups(self, instance: InstanceT) -> tuple[LookupT, ...]: with self._LOCK: return tuple(k for k, v in self._lookup.items() if v == instance) def add(self, instance: InstanceT) -> None: with self._LOCK: lookup_values = self._get_lookups(instance) if instance in self._all: raise ValueError("Instance already in added") self._all.append(instance) for lv in lookup_values: if lv in self._lookup: raise ValueError("lookup value already used for different instance") self._lookup[lv] = instance self._on_add def remove(self, instance: InstanceT): with self._LOCK: for k, v in self._lookup.items(): if v == instance: self._lookup.pop(k) self._all.remove(instance) self._on_remove Now I wonder if a class using this functionality would benefit more from inheriting from it or by making a class field be the instance manager. I know that inheritance is a "is a" relationship while composition is a "has a" relationship, but I feel like in this case it doesn't really help me answer the question. To consider is also that many classes I would use it for would have other classes they should inherit from, so it would lead to multiple inheritance, which I want to avoid if possible. Continue reading...