Как в аннотации типов указать, что тип должен реализовывать какой-то конкретный метод?
Как в аннотации типов указать, что тип должен реализовывать какой-то конкретный метод?
Чаще всего это нужно для специальных методов (например, __gt__ означает что объекты можно сравнивать через оператор >).
К примеру, мы пишем функцию get_max (упрощённый аналог встроенной функции max):
def get_max(l: list[...]) -> ...:
cond = l[0]
for cur in l:
if cur > cond:
cond = cur
return cond
На месте ... должна быть аннотация типа, показывающая, что тип поддерживает сравнение с помощью оператора > (больше). Какой она должна быть?
Ответы (1 шт):
Начиная с версии Python3.8 (PEP 544) доступен такой способ:
Сначала нужно определить класс, наследующий от typing.Protocol и реализующий нужный метод:
class SupportsGreaterThan(typing.Protocol):
def __gt__(self, other): ...
Потом определить такой TypeVar:
GT = typing.TypeVar('GT', bound=SupportsGreaterThan)
И, наконец, использовать его в своей функции:
def get_max(l: list[GT]) -> GT:
... # Реализация такая же
После всех этих действий Mypy предупреждает о неверном типе:
При таком коде:
get_max([1, 2, 3])
get_max([None, None]) # None нельзя сравнивать с помощью оператора `>`!
Он выводит:
main.py:20: error: Value of type variable "GT" of "get_max" cannot be "None" [type-var]
Found 1 error in 1 file (checked 1 source file)