Я хотел бы написать следующий универсальный код Python:
from itertools import chain
from typing import Sequence, Hashable, List, Tuple, Type, TypeVar
SequenceT = TypeVar('SequenceT', bound=Sequence)
HashableT = TypeVar('HashableT', bound=Hashable)
def merge_and_sort_into(seq_type, *iterables):
# type: (Type[SequenceT], *Iterable[HashableT]) -> SequenceT[HashableT]
return seq_type(sorted(set(chain(*iterables))))
def merge_and_sort_into_list(*iterables):
# type: (*Iterable[HashableT]) -> List[HashableT]
return merge_and_sort_into(list, *iterables)
def merge_and_sort_into_tuple(*iterables):
# type: (*Iterable[HashableT]) -> Tuple[HashableT]
return merge_and_sort_into(tuple, *iterables)
Код в порядке, но mypy не нравится тип возврата merge_and_sort_into()
, говоря error: Type variable "SequenceT" used with arguments
. Как я могу передать тип Sequence в функцию, а также использовать этот тип в качестве возвращаемого типа? (примечание: я не фиксирую тот факт, что тип значения для последовательности также должен быть сопоставимым / сортируемым, но давайте просто проигнорируем это).
Вот версия, которую mypy примет, но она нене захватывает ограничение, которое тип, переданный в merge_and_sort_into()
, является его типом возврата, следовательно бросает.
def merge_and_sort_into(seq_type, *iterables):
# type: (Callable[[Iterable[HashableT]], Sequence[HashableT]], *Iterable[HashableT]) -> Sequence[HashableT]
return seq_type(sorted(set(chain(*iterables))))
def merge_and_sort_into_list(*iterables):
# type: (*Iterable[HashableT]) -> List[HashableT]
return cast(List[HashableT], merge_and_sort_into(list, *iterables))
def merge_and_sort_into_tuple(*iterables):
# type: (*Iterable[HashableT]) -> Tuple[HashableT]
return cast(Tuple[HashableT], merge_and_sort_into(tuple, *iterables))