[Python] Python inheritance vs. composition for InstanceManager

Discussão em 'Python' iniciado por Stack, Março 4, 2025.

  1. Stack

    Stack Membro Participativo

    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...

Compartilhe esta Página