Как я могу определить универсальную ковариантную функцию в Python? - PullRequest
0 голосов
/ 14 октября 2019

Я хочу определить функцию example, которая принимает аргумент типа Widget или что-либо, что расширяет Widget и возвращает тот же тип, что и аргумент. Поэтому, если Button extends Widget, вызов example(Button()) возвращает тип Button.

. Я попытался сделать следующее:

T_co = TypeVar('T_co', Widget, covariant=True)

def example(widget: T_co) -> T_co:
  ...

Однако средство проверки типов (Pyright) игнорирует ковариацию,После дальнейших исследований я обнаружил примечание в PEP 484 :

Примечание: Ковариация или контравариация не свойство переменной типа, но свойствоуниверсальный класс, определенный с помощью этой переменной. Дисперсия применима только к универсальным типам;универсальные функции не имеют этого свойства. Последний должен быть определен с использованием только переменных типа без аргументов ключевых слов covariant или contravariant.

Однако, если я попытаюсь определить обобщенную функцию без ковариантного аргумента, как указано в примечании:

T_co = TypeVar('T_co', Widget)

def example(widget: T_co) -> T_co:
  ...

Я могу передавать в функцию только значения типа Widget (не Button).

Как этого добиться?

1 Ответ

0 голосов
/ 14 октября 2019

Мне удалось найти ответ в MyPy документах . Оказывается, я искал bound, а не covariant. Это можно сделать так:

T = TypeVar('T', bound=Widget)

def example(widget: T) -> T:
  ...
...