Как напечатать обобщенную функцию? - PullRequest
2 голосов
/ 28 октября 2019

Скажем, я хочу определить, что-то в Python работает точно так же, как следующая функция в Java:

public <T> void func(T a, T b):
     ...

Этот код просто означает, что func может принимать любые a и b каквходные данные, если они имеют одинаковый тип данных.

Python не имеет явной проверки типа, но теперь я использую mypy для проверки моего кода. Мои попытки следующие:

T = TypeVar('T')

def func(a: Generic[T], b: Generic[T]):
         ...
func(1, 3)  # this should be a legal input since 1 and 3 are both int

и

T = TypeVar('T')

class A(Generic[T]):
    pass

def func(a: A[T], b: A[T]):
    ...
func(1, 3)

Однако mypy сообщает об ошибках для них обоих. Есть ли способ определить такую ​​универсальную функцию, как в Java, чтобы пройти проверку mypy? Я знаю, что для проверки работоспособности моего кода я также могу проверить, равно ли type(a) type(b) внутри функции, но это не моя цель. Меня особенно интересует мой вопрос, как он есть, то есть, как определить такую ​​универсальную функцию для прохождения проверки mypy?

1 Ответ

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

Эта функция Java на самом деле не делает то, что вы хотите, и эквивалент Python не будет делать то, что вы хотите.

Вы хотите убедиться, что функция Java всегда вызываетсяс двумя аргументами одного и того же типа, но любой два объекта, которые вы могли бы передать, имеют общий тип. В частности, любые два объекта являются экземплярами Object. (null и примитивы немного усложняют, но они не остановят вызовы от проверки типов.) Любой вызов будет проверять тип, и ваша попытка использовать непатентованные элементы ничего не даст.

Аналогичноэквивалент Python будет

def func(a: T, b: T):
    ...

, и, как и код Java, любой вызов будет проверять тип, потому что любые два объекта являются экземплярами object.


Нет никакого способауказать ограничение type(a) is type(b) с аннотациями типов. Во всяком случае, обычно это неправильное ограничение. Обычно вы хотите указать, что аргументы каким-то образом совместимы друг с другом. К сожалению, на самом деле нет хорошего способа сделать это.

Например, если вы хотите указать, что два аргумента в Java сопоставимы, это будет

public <T extends Comparable<T>> void func(T a, T b) {...}

Однако переменные типа Python не поддерживают параметризованные границы, подобные этой.

...