Как я могу указать подтип нескольких типов (включая общие типы, такие как Callable) в аннотациях типов Python? - PullRequest
0 голосов
/ 11 июля 2020

Одним из очевидных примеров этого является множественное наследование: если у меня есть классы Foo и Bar, я могу создать класс Baz, который наследуется от обоих (class Baz(Foo, Bar): ...). Однако я мог бы также создать другой класс с другим поведением, который по-прежнему наследуется как от Foo, так и от Bar ... или я мог бы унаследовать от третьего класса, что создает совершенно другой тип. Очевидно, что это нишевый вариант использования, но поддерживается ли это в аннотациях типа Python? В данном примере я не хочу специально писать Baz - мне нужно знать только тот факт, что тип - это и Foo, и Bar, но это также может быть что угодно. Я думал что-то вроде param: Foo | Bar или param: typing.Multiple[Foo, Bar].

Мой конкретный c вариант использования: я хочу использовать синтаксис Callable для указания типа параметра и возвращаемого значения (например, Callable[..., bool] ), но мне также нужно убедиться, что аргумент - это FunctionType, то есть не класс или builtin_function_or_method. Конечно, я мог бы просто указать это в строке документации - но поддерживается ли это в аннотациях типов таким образом, чтобы они работали со средствами проверки типов?

1 Ответ

0 голосов
/ 11 июля 2020

Существует ограниченная версия этого класса протокола ( PEP , docs ), однако он поддерживает только переменные типа (Protocol[T]) и конкретные типы (class MyProtocol(FunctionType, Protocol)), но не общие типы, такие как Any, Union, Callable, Iterator и др. c. Итак, примерный случай в вопросе может быть реализован как

class FooAndBar(Foo, Bar, typing.Protocol): ...

, но вариант использования, упомянутый ниже, кажется невозможным ( может быть возможно в конечном итоге ), поэтому сейчас я бы либо определите протокол только с теми членами, которые вам нужны, используйте строку в качестве подсказки типа или укажите это в строке документации.

Дополнительное примечание: если вы используете IntelliJ IDE, вы можете написать

assert isinstance(param, (Foo, Bar))

, который в целях проверки типа даст тот же результат, что и гипотетический param: Intersection[Foo, Bar] в любом последующем коде.

...