Каким образом следует правильно аннотировать словарь в Python?

В статьях и книгах можно встретить различные примеры аннотирования словарей, такие как: 

```python
from typing import Dict, Mapped

dict_one = dict[str, Any]
dict_two = Dict[str, Any]
dict_three = Mapped[str, Any]
```

Какова разница между этими тремя подходами? В каких ситуациях следует предпочесть каждый из них?
  • 14 сентября 2024 г. 5:23
Ответы на вопрос 2
В Python существует несколько способов аннотирования словарей, каждый из которых имеет свои особенности и использование. Давайте разберем предложенные вами варианты.

### 1. `dict[str, Any]`

Это синтаксис, который появился в Python 3.9 и использует стандартный тип `dict`. Он более читаемый и удобный, поскольку вы можете использовать синтаксис, аналогичный созданию экземпляров. Вот пример:

```python
from typing import Any

dict_one: dict[str, Any] = {'key': 'value'}
```

**Когда использовать?** 
- Рекомендуется использовать этот вариант, если вы работаете с Python 3.9 и выше, так как он составляет более современный синтаксис, который легче понять и читаем. 

### 2. `Dict[str, Any]`

Это способ, использующий модуль `typing`, который позволяет вам явно указать, что вы используете типы для аннотации. Этот синтаксис был доступен еще до появления синтаксиса в виде квадратных скобок в версии 3.9.

```python
from typing import Dict, Any

dict_two: Dict[str, Any] = {'key': 'value'}
```

**Когда использовать?** 
- Этот вариант подходит, если вы работаете с более ранними версиями Python (до 3.9). Хотя можно использовать и в новых версиях, большинство разработчиков предпочитает использовать `dict[str, Any]` в современных проектах.

### 3. `Mapped[str, Any]`

`Mapped` — это встроенная часть библиотеки `typing`, предназначенная в основном для работы с ORM или другими библиотеками, участвующими в маппинге (например, SQLAlchemy). Это означает, что `Mapped` не совсем подходит для обычного использования словарей, так как он больше связан с маппингом атрибутов к базе данных.

```python
from typing import Mapped

dict_three: Mapped[str, Any] = {'key': 'value'}  # это не правильное использование
```

**Когда использовать?** 
- Можете использовать `Mapped`, если вы работаете с ORM и вам нужно обозначить, что атрибуты класса должны быть связаны с колонками в базе данных. Для простых словарей этот подход не подходит.

### Общие рекомендации

- Если вы используете Python 3.9 или выше, используйте `dict[str, Any]` для аннотирования словарей.
- Если вы работаете с Python 3.8 или ниже, используйте `Dict[str, Any]`.
- Избегайте использования `Mapped` для аннотирования обычных словарей в Python, так как это не его основная цель.
Варианты 1 и 2 ссылаются на вполне конкретный класс dict. Когда typing только ввели, стандартынй dict не поддерживал такую запись, поэтому создали псевдоним typing.Dict. Потом к этому типу (а также к tuple и list) прикрутили возможность вести себя как генерик. Сейчас Dict, List и Tuple потихоньку планируют выводить из употребления. Они deprecated начиная с питона 3.9. 
Вариант 3 - это любой объект, который ведёт себя как словарь, не обязательно именно dict. Но с 3.9 это алиас для collections.abc.Mapping, по той же самой причине.

Так что вариант 2 и 3 имеет смысл, только если тебе нужно поддерживать питон 3.8 и младше.
Выбор между вариантом dict и collections.abc.Mapping зависит от того, что именно тебе нужно - вот прямо dict, или просто что-то словареподобное. См. список методов Mapping тут .
Похожие вопросы