У меня есть фрагмент кода, который выглядит примерно так:
T = TypeVar('T')
def filter_by_type(cls: Type[T]) -> Iterable[T]:
for val in some_other_iterable():
if isinstance(val, cls):
yield val
Пока все хорошо. Но теперь я понял, что смогу передать не только один класс, но и кортеж классов. Сам нетипизированный код Python даже не требует для этого никаких изменений, поскольку isinstance
действительно принимает кортеж в качестве второго аргумента. Но аннотации типов теперь стали очень сложными. По сути, я хочу следующее:
def filter_by_type(cls: Tuple[Type[T1], Type[T2], ...]]) -> Iterable[Union[T1, T2, ...]]:
В идеале я бы имел вышеуказанное в дополнение к исходной версии, и я считаю, что могу использовать для этого @ overload .
Я знаю, что возможно использовать Tuple[T, ...]
для обозначения кортежа с неизвестным числом элементов, все типа T
, но я не могу себе представить, чтобы это разумно распространялось на ситуацию, когда перечислено более одного явного элемента, как в моем случае.
Я сомневаюсь, что система pytype способна указать там все, что я хочу. Что ближе всего я могу найти? Лучшее, что у меня есть, - это перегрузки для фиксированного количества типов.
T1 = TypeVar('T1')
T2 = TypeVar('T2')
T3 = TypeVar('T3')
@overload
def filter_by_type(cls: Type[T1]) -> Iterable[T1]: ...
@overload
def filter_by_type(cls: Tuple[Type[T1]]) -> Iterable[T1]: ...
@overload
def filter_by_type(cls: Tuple[Type[T1], Type[T2]]) -> Iterable[Union[T1, T2]]: ...
@overload
def filter_by_type(cls: Tuple[Type[T1], Type[T2], Type[T3]]) -> Iterable[Union[T1, T2, T3]]: ...
def filter_by_type(cls):
for val in some_other_iterable():
if isinstance(val, cls):
yield val