На этом шаге мы приведем правила записи аннотации типов и разберем, как они используются.
Аннотации типов добавляются в строку кода, где объявлена переменная или функция. Признаком начала аннотации типа для переменной или параметра функции служит двоеточие (:), а для типа, возвращаемого функцией, - стрелка (->). Например, рассмотрим следующую строку кода на Python:
def repeat(item, times):
Можете ли вы сказать, не читая определение функции, что эта функция должна делать? Распечатать строку определенное количество раз? Или что-то еще? Конечно, для того, чтобы выяснить, что должна делать функция, можно прочитать ее определение, но это займет больше времени. Да и автор этой функции, к сожалению, не предоставил никакой документации. Попробуем еще раз, с аннотациями типа:
def repeat(item: Any, times: int) -> List[Any]:
Так гораздо понятнее. Достаточно просто взглянуть на аннотации типов, и станет ясно, что данная функция принимает элемент любого типа и возвращает список List, заполненный этим элементом, заданное число раз. Конечно, документация по-прежнему поможет сделать функцию более понятной, но пользователь библиотеки теперь хотя бы знает, какие значения следует предоставлять этой функции и каких значений можно ожидать на выходе.
Предположим, что библиотека, в которой используется данная функция, работает только с числами с плавающей точкой и эта функция должна была служить для создания списков, которые будут применяться в других функциях. Мы можем легко изменить аннотации типов и ввести ограничение для чисел с плавающей точкой:
def repeat(item: float, times: int) -> List[float]:
Теперь ясно, что значение item должно иметь тип float и возвращаемый список должен заполняться числами типа float. Ну хорошо, "должен" в данном случае - слишком сильно сказано. Начиная с Python 3.7, аннотации типов не имеют никакого отношения к выполнению программы на Python. Это действительно лишь аннотации, а не требования. Во время выполнения программа на Python может полностью игнорировать аннотации типов и нарушать любые предполагаемые ограничения. Однако инструмент проверки типов может учитывать аннотации типов во время разработки программы и сообщать программисту о наличии некорректных вызовов функций. Вызов
repeat("hello", 30)
Рассмотрим еще один пример. На этот раз это аннотация типа для объявления переменной:
myStrs: List[str] = repeat(4.2, 2)
Эта аннотация типа не имеет смысла. Она говорит о том, что переменная myStrs должна представлять собой список строк. Но, как мы знаем из предыдущей аннотации типа, repeat() возвращает список чисел с плавающей точкой. К тому же, поскольку Python, начиная с версии 3.7, не проверяет аннотации типов на корректность во время выполнения программы, данная ошибочная аннотация типа не повлияет на работу программы. Однако средство проверки типов может обнаружить эту ошибку программиста или неправильное представление о правильном типе, прежде чем они приведут к катастрофическим последствиям.
На следующем шаге мы рассмотрим, почему полезны аннотации типов.