Дженерики
Что если мы хотим написать обобщённую функцию, которая принимает на вход итерируемую структуру, то есть структуру, по которой можно итерироваться, и возвращает результат первой итерации?
from typing import TypeVar, Iterable
T = TypeVar("T")
def first(iterable: Iterable[T]) -> T | None:
for element in iterable:
return element
print(first(["one", "two"])) # one
print(first((100, 200))) # 200
Как видите, типом данных в этой итерируемой структуре iterable
могут быть любые данные, а наши type hinting в функции first
говорят буквально, что функция принимает на вход итерабельную структуру данных, каждый элемент которой имеет тип T
, и функция возвращает тот же тип T
. Тип T
при этом может быть любым.
Это так называемые дженерики, то есть обобщённые типы.
Причём имя T
здесь это пример, он часто используется именно так, T
, от Type, но название типа может быть и любым другим.
Помимо дженериков можно сохранять отдельные типы для лучшей читаемости кода и подсказки читателю, что именно за данные здесь хранятся:
from dataclasses import dataclass
Phone = str
@dataclass
class User:
user_id: int
phone: Phone
def get_user_phone(user: User) -> Phone:
return user.phone
Мы уже использовали это в коде приложения погоды, когда задавали псевдоним для градусов Цельсия.