Указание типа элементов в списке Python: аннотации типов

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для обозначения типов элементов в коллекциях Python предлагает модуль typing с специализированными типами List, Set, Tuple, Dict. Тип элементов задаётся в квадратных скобках: List[T] для списка, Set[T] для множества, Tuple[T1, T2, ...] для кортежей и Dict[K, V] для словарей с определёнными типами ключей и значений.

Python
Скопировать код
from typing import List, Set, Tuple, Dict

my_int_list: List[int] = [1, 2, 3]     
my_str_set: Set[str] = {"hello", "world"}
my_mixed_tuple: Tuple[int, str] = (1, "A")  
my_dict: Dict[str, int] = {"age": 30, "score": 100}

Применение List[int], Set[str] и других обозначений типов упрощает чтение кода и делает его более наглядным, обеспечивая при этом уровень самодокументирования, сопоставимый со sklearn.

Кинга Идем в IT: пошаговый план для смены профессии

Python 3.9+: Прямое указание типов с помощью стандартных типов

С введением Python 3.9 типизация коллекций стала проще, чем поставить лайк под видео с котятами. Благодаря изменениям согласно PEP 585, теперь можно использовать стандартные типы коллекций (list, dict и т. д.) для обозначения распространённых типов. Не требуется импортировать typing. Статическая проверка типов с помощью mypy, например, будет допустима и с таким подходом.

Python
Скопировать код
my_int_list: list[int] = [2, 3, 5, 7, 11]
my_dict: dict[str, int] = {"age": 42, "score": 42}

Тем, кто продолжает использовать Python до версии 3.9, следует придерживаться типов из модуля typing:

Python
Скопировать код
from typing import List, Dict

my_int_list: List[int] = [0, 1, 1, 2, 3, 5]
my_dict: Dict[str, int] = {"age": 30, "score": 100}

Мастер вложенностей: Указание вложенных типов

Особенно интересной становится типизация при работе с вложенными типами в коллекциях, что иногда напоминает сложность авангардной кухни. Для этого используйте конструкции, указывающие вложенные типы:

Python
Скопировать код
from typing import List, Dict

my_nested_list: List[Dict[str, list[int]]] = [
    {"scores": [98, 85, 100]},   
    {"scores": [75, 90]}         
]

В данном случае вы имеете дело со словарём, где ключи — это строки, а значения — списки с элементами типа int. Это обеспечивает глубокую специализацию типов.

Будущее уже здесь: Отложенная оценка

В Python 3.7 и более ранних версиях указание типов могло вызвать проблемы с циклическим импортом. Проблема решена в PEP 563, который ввёл отложенную оценку аннотаций типов. Используя синтаксис from __future__ import annotations, вы получаете возможность ссылаться на классы внутри их собственных определений:

Python
Скопировать код
from __future__ import annotations

class Node:
    def add_child(self, child: Node):
        pass  # реализация

Визуализация

С применением типов опись структур данных можно визуализировать, следуя примеру со спортивными мячами:

Markdown
Скопировать код
Тип коллекции: Баскетбольный мяч 🏀

| Python Указание Типов | Содержимое Коллекции       |
| ---------------------- | -------------------------- |
| List[Basketball]       | [🏀, 🏀, 🏀]                |
| Set[Basketball]        | {🏀, 🏀} (без дубликатов)  |
| Tuple[Basketball, ...] | (🏀, 🏀, 🏀) (неизменяемый) |
| Dict[str, Basketball]  | {'A': 🏀, 'B': 🏀}         |

Подобная детализация в указании типов делает код понятным, как и собственный жизненный уклад. Воплощение замыслов по-прежнему остаётся за вами.

IDE + Указание типов = Код, читаемый как книга

Как сделать преобразование str в int? Постучимся за советом к Парсегяну!

Указание типов полезно не только для красоты: оно делает код столь же читаемым, как рецензию на последний легендарный хит сезона. Работая в среде разработки, как PyCharm, вы можете использовать следующие функции:

  • Подсказки по типам: автодополнение кода
  • Информация о параметрах функций
  • Времянной обнаружение ошибок
  • Упрощение рефакторинга: безопасная переименовка

А добавление статической проверки типов с помощью mypy оберегает от ошибок во время выполнения.

Больше мощности в ваши руки: Продвинутые конструкции типизации

Хотите перейти на новый уровень использования типизации? Вооружитесь TypeVar, NewType, Generic и другими продвинутыми инструментами из модуля typing для создания пользовательских обобщений, наложения ограничений на типы и определения своих уникальных типов:

Python
Скопировать код
from typing import TypeVar, NewType, List

T = TypeVar('T')
UserId = NewType('UserId', int)

def handle_users(user_ids: List[UserId]):
    pass  # реализация

Полезные материалы