Python Typehints: Обобщения с ограничением на реализацию не универсального c интерфейса - PullRequest
0 голосов
/ 21 января 2020

Рассмотрим следующий параметр:

  • Реализация обобщенного c MutableSequence, который позволяет определить в своем __init__, как получить доступ к определенным ключевым свойствам для выполнения проверок согласованности во время выполнения (пример: обеспечить уникальность ключевого свойства в MutableSequence)
class UniqueKeyedList(MutableSequence[T], collections.abc.MutableSequence):
    """A mutable sequence that maintains uniqueness of a key-property accessible through a determined selector function.

    Args:
         contents (Collection[T]): A collection of items to initialise the `UniqueKeyedList` with.
         key_getter (Callable[[T], Hashable]): Getter function to access key properties of `contents` items.

    Raises:
        ValueError: Raised if the input `contents` do not fulfill the uniqueness of keys property.
    """
    def __init__(self, contents: Collection[T], *, key_getter=Callable[[T], Hashable]):
        if not _fulfills_uniqueness_property(values=contents, key_getter=key_getter):
            raise ValueError("Collection must not contain multiple entries with same key.")
        self._contents = list(contents)
        self._key = key_getter

    # other implementations for abstract methods here
  • Подкласс UniqueKeyedList с фиксированным key_getter и требованием, что все элементы в UniqueKeyedList должны реализовать интерфейс, обеспечивающий постоянный доступ key_getter к существующему свойству:
class IDIdentifiable(ABC):
    """Interface for objects implementing an `id_` property returning a hashable value.
    """
    @property
    @abstractmethod
    def id_(self) -> Hashable:
        raise NotImplementedError


class IDUniqueItemList(UniqueKeyedList[IDIdentifiable]):
    """`UniqueKeyedList` composed of `IDIdentifiable` objects.

    Args:
        args (Collection[IDIdentifiable]): A collection of `IDIdentifiable` objects to initialise the unique item list
            with.

    Raises:
        ValueError: Raised if any operation violates the unique key constraint.
    """
    def __init__(self, args: Collection[IDIdentifiable]):
        super().__init__(args, key_getter=lambda x: x.id_)

Цель: Я бы хотел сохранить IDUniqueItemList в качестве обобщенного c класс, так что я могу установить шрифты для отдельных элементов, хранящихся в нем (например, IDUniqueItemList[MyClassImplementingIDIdentifiable]). Однако я не могу просто сделать IDUniqueItemList generi c, не убедившись, что используемый мной TypeVar реализует IDIdentifiable. Создание IDIdentifiable generi c кажется неправильным.

Как лучше всего реализовать такую ​​настройку, поддерживая универсальность подкласса IDUniqueItemList?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...