📜 Коллекции: стиль Python <3.9
# old_style.py
from typing import Dict, List, Set, Tuple
def process_numbers(numbers: List[int]) -> List[int]:
return [n ** 2 for n in numbers]
def get_point() -> Tuple[str, float, float]:
return "A", 1.5, 2.5
def count_words(text: str) -> Dict[str, int]:
words = text.split()
return {word: words.count(word) for word in words}
def unique_chars(text: str) -> Set[str]:
return set(text)
Что здесь происходит: каждый generic-тип импортируется из модуля typing с заглавной буквы. Это работает во всех версиях Python, начиная с 3.5, но выглядит многословно.
❌ Почему старый подход менее удобен сейчас
- Лишние импорты увеличивают начало файла.
- Заглавные буквы
List/Dictлегко перепутать со встроеннымиlist/dict. - Новые разработчики чаще видят современный синтаксис в документации и библиотеках.
✅ Современный вариант (Python 3.9+)
# modern_style.py
def process_numbers(numbers: list[int]) -> list[int]:
return [n ** 2 for n in numbers]
def get_point() -> tuple[str, float, float]:
return "A", 1.5, 2.5
def count_words(text: str) -> dict[str, int]:
words = text.split()
return {word: words.count(word) for word in words}
def unique_chars(text: str) -> set[str]:
return set(text)
Что улучшилось: код читает естественнее — тип совпадает с именем встроенного типа, а квадратные скобки указывают параметры типа.
- Нет лишних импортов.
- Меньше визуального шума.
- Соответствует современной документации Python.
📜 Объединение типов: старый стиль
# old_union.py
from typing import Union
def calculate(value: Union[int, float]) -> float:
return value ** 2
✅ Современный вариант (Python 3.10+)
# modern_union.py
def calculate(value: int | float) -> float:
return value ** 2
def find_user(user_id: int) -> str | None:
users = {1: "Alice", 2: "Bob"}
return users.get(user_id)
Что улучшилось: оператор | читается как «или», а str | None заменяет Optional[str].
📜 Docstrings: reST/Epytext из исходника
def greet(name: str) -> str:
"""
Функция принимает имя и возвращает строку приветствия.
:param name: Имя пользователя.
:return: Приветственное сообщение.
"""
return f"Hello, {name}!"
Что здесь происходит: классический формат с полями :param и :return хорошо поддерживается инструментами и IDE.
✅ Альтернативные форматы docstring
🕰️ Когда старый подход ещё можно встретить
- Кодовая база, которая поддерживает Python 3.7–3.8.
- Библиотеки, старающиеся сохранить совместимость со старыми версиями.
- Legacy-проекты, где миграция на встроенные generic-типы ещё не проведена.
В таких случаях можно постепенно переходить к новому синтаксису или использовать from __future__ import annotations, чтобы писать новый синтаксис даже в старых версиях (строковые аннотации).