Аннотация типов в python

Зачем надо?

  • проверка типов
  • расширение функционала IDE в части предоставления информации об ожидаемых типах аргументов и типе возвращаемого значения у функций;
  • перегрузка функций и работа с дженериками;
  • взаимодействие с другими языками;
  • использование в предикатных логических функциях;
  • маппинг запросов в базах данных;
  • маршалинг параметров в RPC (удаленный вызов процедур)

Контроль типов

PEP

  • PEP 3107 — Function Annotations
  • PEP 484 — Type Hints
  • PEP 526 — Syntax for Variable Annotations
  • PEP 563 — Postponed Evaluation of Annotations

Аннотации не имеют никакого семантического значения для интерпретатора Python и предназначены только для анализа сторонними приложениями.

У подхода работы с аннотация до этого PEP’а был ряд проблем связанных с тем, что определение типов переменных (в функциях, классах и т.п.) происходит во время импорта модуля, и может сложится такая ситуация, что тип переменной объявлен, но информации об этом типе ещё нет, в таком случае тип указывают в виде строки – в кавычках. В PEP 563 предлагается использовать отложенную обработку аннотаций, это позволяет определять переменные до получения информации об их типах и ускоряет выполнение программы, т.к. при загрузке модулей не будет тратится время на проверку типов – это будет сделано перед работой с переменными.

Аннотации локальных переменных недоступны во время выполнения, но аннотации глобальных переменных, атрибутов классов и функций хранятся в специальном атрибуте __annotations__ модулей, классов и функций соответственно.

Аннотации в функциях

def repeater(s: str, n: int) -> str:
   return s * n

Тут имя_аргумента: аннотация аннотация аргумента. Аннотация возвращаемого функцией значения def имя_функции() -> тип. Доступ к аннотации осуществляется через repeater.__annotations__. Мы получим это;

{'n': int, 'return': str, 's': str}

Аннотация переменных

Есть три варианта

var = value # type: annotation
var: annotation; var = value
var: annotation = value

# example
name = John # type: str
name:str; name = John
name: str = John

# список
scores: List[int] = []
scores.append(1)
# кортеж
pack: Tuple[int, ] = (1, 2, 3)
# логическая переменная
flag: bool
flag = True
# класс
class Point:
    x: int
    y: int
    def __init__(self, x: int, y: int):
         self.x = x
         self.y = y

a:int = 10
b:int = 15
def sq_sum(v1:int, v2:int) -> int:
    return v1**2 + v2**2
print(sq_sum(a, b))

Статья