Type Hints в Python и проверка типов с инструментом mypy
В этом уроке вы узнаете о подсказках типов данных (Type Hints) в Python и о том, как использовать инструмент mypy для статической проверки типов.
- Что такое подсказки типов в Python?
- Инструмент статической проверки типа: mypy
- Подсказки типов и вывод типов
- Добавление подсказок для нескольких типов
- Присвоение псевдонимов
- Добавление подсказок типов для списков, словарей и множеств
- Тип None
Что такое подсказки типов в Python?
Некоторые языки программирования, например C/C++, имеют статическую типизацию. Это означает, что вам необходимо заранее объявить типы переменных, параметров и возвращаемых значений функции. Предопределенные типы позволяют компиляторам проверять код перед компиляцией и запуском программы.
Python использует динамическую типизацию, при которой переменные, параметры и возвращаемые значения функции могут быть любого типа. Кроме того, типы переменных могут меняться во время работы программы.
Как правило, динамическая типизация упрощает программирование и вызывает непредвиденные ошибки, которые можно обнаружить только до тех пор, пока программа не запустится.
Type Hints в Python предоставляют вам дополнительную статическую типизацию, позволяющую использовать преимущества как статической, так и динамической типизации.
В следующем примере определяется простая функция, которая принимает строку и возвращает другую строку:
def say_hi(name): return f'Hi {name}' greeting = say_hi('John') print(greeting)
Вот синтаксис добавления подсказок типа данных к параметру и возвращаемому значению функции:
parameter: type -> type
Например, ниже показано, как использовать подсказки типа для параметра name и возвращаемого значения функции Say_hi():
def say_hi(name: str) -> str: return f'Hi {name}' greeting = say_hi('John') print(greeting)
Выход:
Hi John
В этом новом синтаксисе параметр name имеет тип str:
name: str
И возвращаемое значение функции say_hi() также имеет тип str:
-> str
Помимо типа str, для подсказок типов можно использовать другие встроенные типы, такие как int, float, bool и bytes.
Важно отметить, что интерпретатор Python полностью игнорирует подсказки типов. Если вы передадите число функции say_hi(), программа запустится без каких-либо предупреждений или ошибок:
def say_hi(name: str) -> str: return f'Hi {name}' greeting = say_hi(123) print(greeting)
Выход:
Hi 123
Чтобы проверить синтаксис подсказок типов, вам необходимо использовать инструмент проверки статического типа.
Инструмент статической проверки типа: mypy
В Python нет официального инструмента статической проверки типов. На данный момент самым популярным сторонним инструментом является Mypy. Поскольку Mypy — сторонний пакет, вам необходимо установить его с помощью следующей команды pip:
pip instal mypy
После установки mypy вы можете использовать его для проверки типа перед запуском программы, используя следующую команду:
mypy app.py
Появится следующее сообщение:
app.py:5: error: Argument 1 to "say_hi" has incompatible type "int"; expected "str" Found 1 error in 1 file(checked 1 source file)
Ошибка указывает на то, что аргумент say_hi имеет значение int, а ожидаемый тип — str.
Если вы снова измените аргумент на строку и снова запустите mypy, появится сообщение об успехе:
Success: no issues found in 1 source file
Подсказки типов и вывод типов
При определении переменной вы можете добавить подсказку типа следующим образом:
name: str = 'John'
Тип переменной имени — str. Если вы присвоите переменной имени значение, не являющееся строкой, средство проверки статического типа выдаст ошибку. Например:
name: str = 'Hello' name = 100
Ошибка:
app.py:2: error: Incompatible types in assignment(expression has type "int", variable has type "str") Found 1 error in 1 file(checked 1 source file)
Добавление типа к переменной не является необходимым, поскольку средства проверки статического типа обычно могут определить тип на основе значения, присвоенного переменной.
В этом примере значением name является литеральная строка, поэтому средство проверки статического типа определит тип переменной name как str. Например:
name = 'Hello' name = 100
Выдаст ту же ошибку:
app.py:2: error: Incompatible types in assignment(expression has type "int", variable has type "str") Found 1 error in 1 file(checked 1 source file)
Добавление подсказок для нескольких типов
Следующая функция add() возвращает сумму двух чисел:
def add(x, y): return x + y
Числа могут быть целыми числами или числами с плавающей запятой. Вы можете использовать модуль для установки type hints для нескольких типов.
Сначала импортируйте Union из модуля typing:
from typing import Union
Во-вторых, используйте Union для создания типа объединения Union, включающего int и float:
def add(x: Union[int, float], y: Union[int, float]) -> Union[int, float]: return x + y
Вот полный исходный код:
from typing import Union def add(x: Union[int, float], y: Union[int, float]) -> Union[int, float]: return x + y
Начиная с Python 3.10, вы можете использовать X | Синтаксис Y для создания типа Union, например:
def add(x: int | float, y: int | float) -> int | float: return x + y
Присвоение псевдонимов
Python позволяет вам назначать псевдоним типу и использовать его для подсказок типов. Например:
from typing import Union number = Union[int, float] def add(x: number, y: number) -> number: return x + y
В этом примере мы присваиваем типу Union[int, float] псевдоним Number и используем псевдоним Number в функции add().
Добавление подсказок типов для списков, словарей и множеств
Вы можете использовать следующие встроенные типы, чтобы установить подсказки типов для списка, словаря и множества:
- list
- dict
- set
Если вы введете подсказки в переменную в виде списка, а затем присвоите ей словарь, вы получите ошибку:
ratings: list = [1, 2, 3] ratings = {1: 'Bad', 2: 'average', 3: 'Good'}
Ошибка:
app.py:3: error: Incompatible types in assignment(expression has type "Dict[int, str]", variable has type "List[Any]") Found 1 error in 1 file(checked 1 source file)
Чтобы указать типы значений в списке, словаре и наборах, вы можете использовать псевдонимы типов из модуля typing:
Псевдоним типа | Встроенный тип |
---|---|
List | list |
Tuple | tuple |
Dict | dict |
Set | set |
Frozenset | frozenset |
Sequence | Для списка, кортежа и любого другого типа данных последовательности. |
Mapping | Для dict, set, Frozeset и любого другого типа данных сопоставления. |
ByteString | Для типов bytes, bytearray и MemoryView. |
Например, следующее определяет список целых чисел:
from typing import List ratings: List[int] = [1, 2, 3]
Тип None
Если функция не возвращает значение явно, вы можете использовать None для ввода подсказки возвращаемого значения. Например:
def log(message: str) -> None: print(message)