Поиск подходящей подсказки типа Python, например, подписи встроенной функции map () - PullRequest
2 голосов
/ 19 октября 2019

Описание

В Python 3.5 или выше поддерживаются подсказки типа (см. здесь для получения дополнительной информации). Тем не менее, правильное использование для распространенных типов недостаточно хорошо документировано.

Например, с официального сайта я могу собрать следующие (правильные) выражения:

String

# The function signature of greeting is: Callable[[str], str]
def greeting(name: str) -> str:
    return 'Hello ' + name

Целое число

# The function signature of add is: Callable[[int, int], int]
def add(a: int, b: int) -> int:
    return a + b

Число с плавающей запятой

# The default value of x is 1.0
def reciprocal(x: float = 1.0) -> float:
    from math import nan
    if x == 0:
        return nan
    return 1 / x

Список

from typing import List, TypeVar

T = TypeVar('T')

def repeat(x: T, n: int) -> List[T]:
    return [x] * n

Кортеж

from typing import Tuple, TypeVar

T = TypeVar('T')

def double(x: T) -> Tuple[T, T]:
    return (x, x)

Вопросы

Мои вопросы:

1. Каков тип возврата map?

from typing import Iterable

# Is this correct?
x: Iterable[float] = map(int.__float__, [1, 2, 3])

Я не уверен, что это правильный тип подсказки для x выше.

2. В более широком смысле, что такое «сигнатура функции» map?

from typing import Callable, Iterable, TypeVar

T = TypeVar('T')
U = TypeVar('U')

# In the above usage, the type of the map function seems to be:
Function1 = Callable[[T], U]
typeOfMap = Callable[[Function1, Iterable[T]], Iterable[U]]

# Or in one line:
typeOfMap = Callable[[Callable[[T], U], Iterable[T]], Iterable[U]]

Но на самом деле функция map может принимать несколько итераций. задокументировано как:

map(function, iterable, ...)

Это можно использовать так:

# The result is: [['A'], ['B', 'B'], ['C', 'C', 'C']]
result = list(map(repeat, ['A', 'B', 'C'], [1, 2, 3]))

T1 = TypeVar('T1')
T2 = TypeVar('T2')
R = TypeVar('R')

# So, the type of map function in this usage seems to be:
Function2 = Callable[[T1, T2], R]
typeOfMap = Callable[[Function2, Iterable[T1], Iterable[T2]], Iterable[R]]

В общемЯ думаю, это должно быть что-то вроде ниже, но это не правильный способ написать это:

FunctionN = Callable[[T1, T2, ..., Tn], R]
typeOfMap = Callable[[FunctionN, Iterable[T1], Iterable[T2], ..., Iterable[Tn]], Iterable[R]]

Итак, как правильно написать это?

3. В общем, где я могу найти правильную подсказку типа функции / метода Python, включая встроенные, те, которые есть в основных библиотеках?

Они нужны мне в основном для целей обучения.

4. Есть ли способ вывести результат вывода типа, вычисленный компилятором / интерпретатором, как в Haskell или Erlang?

Я знаю, Haskell и Erlang являются функциональными языками программирования, а переменные являются неизменяемыми, поэтомугораздо проще сделать это возможным, но на всякий случай, если Python также имеет аналогичные функции, я хотел бы знать.

5. Есть ли способ проверить правильность подсказки для моего типа?

Или, по крайней мере, пусть он покажет мне предупреждение / ошибку во время компиляции / выполнения, чтобы я знал, что что-то не так.

Ссылки

На момент написания этой статьи последняя стабильная версия - 3.8.0.

1 Ответ

2 голосов
/ 19 октября 2019

1. Какой тип возврата map?

* Возвращаемое значение 1008 * в настоящее время набирается как Iterator[T]. Поскольку итераторы являются итераторами, ваша аннотация x: Iterable[float] = map(int.__float__, [1, 2, 3]) действительна. (Также просто напишите map(float, [1, 2, 3]).)

2. В более широком смысле, что такое «сигнатура функции» карты?

В настоящее время невозможно представить, поэтому * * * * * * * typehed имеет перегрузки для до 6 общих параметров * 1023. *. ( одна связанная проблема )

3. В общем, где я могу найти правильную подсказку типа функции / метода Python, включая встроенные, те, которые есть в основных библиотеках?

Они нужны мне в основном для целей обучения.

Типизированный репозиторий Python . Обратите внимание, что для не целей обучения - на практике - обычно вы должны либо позволить выводить тип, либо использовать любой тип, который имеет смысл, а не самый точный возможный тип.

Вы также можете использовать reveal_type - см. Ниже.

4. Есть ли способ вывести результат вывода типа, вычисленный компилятором / интерпретатором, как в Haskell или Erlang?

Я знаю, Haskell и Erlang являются функциональными языками программирования, а переменные являются неизменяемыми, поэтому было быгораздо проще сделать это возможным, но на всякий случай, если у Python также есть аналогичные функции, я хотел бы знать.

Это зависит от вашей проверки типов. У Mypy reveal_type.

x = map(float, [1, 2, 3])
reveal_type(x)  # note: Revealed type is 'typing.Iterator[builtins.float*]'

5. Есть ли способ проверить правильность подсказки для моего типа?

Или, по крайней мере, пусть он покажет мне предупреждение / ошибку во время компиляции / выполнения, чтобы я знал, что что-то не так.

Статически, вот что такое проверка типов. (Например, Mypy сказал бы вам, если бы ваш x намек был неверным.) Он не может поймать все, особенно в таком динамическом языке, как Python, но это характер программирования.

Естьнесколько проектов, которые делают некоторый уровень утверждений времени выполнения, основанных на аннотациях типов, но ни один из них я не использовал или действительно не потрудился бы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...