Сравнение полей namedtuple и аннотаций NamedTuple

Сравнение полей namedtuple и аннотаций NamedTuple

@python_quiz

Разберем этот квиз

Кратко: в примере ниже выражение печатает False. Разберёмся, почему так происходит, и как правильно сравнивать содержимое.

Условие (код)

python

Что возвращают _fields и __annotations__.keys()

  • Для экземпляра namedtuple атрибут _fields — это кортеж строк:

- Пример: ('name', 'age')
- Тип: tuple

  • Для класса, унаследованного от typing.NamedTuple, __annotations__ — словарь аннотаций атрибутов, а __annotations__.keys() возвращает view-объект dict_keys:

- Пример: dict_keys(['name', 'age'])
- Тип: dict_keys (view object)

Они содержат одинаковые строковые имена, но принадлежат разным типам.

Почему результат False

Операция == сравнивает не только содержимое, но и поведение сравнения между объектами разных типов. Сравнение кортежа и dict_keys не приводит к приведению типов и просто даёт False (не возникает исключений). Поэтому вывод будет False.

Демонстрация — изучим типы и сравнения

python

Обратите внимание: если привести dict_keys к кортежу (или списоку), сравнение по содержимому даст True.

Как правильно сравнивать

Если нужно сопоставить именно имена полей, приведение типов избавит от проблемы:

  • Сравнение в виде списков/кортежей:
python
  • Или сравнение как множества (если порядок не важен):
python

Выбор метода зависит от того, важен ли порядок полей.

Анализ возможных вариантов ответов

  • "Выведет True": неверно — хотя строки совпадают по содержанию, объекты разных типов сравниваются как разные и дают False.
  • "Выведет False": корректное поведение, объясняется разными типами возвращаемых объектов.
  • "Поднимет TypeError": неверно — операция равенства между кортежем и dict_keys не вызывает исключение.
  • "Поднимет AttributeError": неверно — оба атрибута существуют: _fields у namedtuple-экземпляра и __annotations__ у класса NamedTuple.

Вывод

Хотя имена полей в обоих структурах совпадают, _fields — кортеж, а __annotations__.keys() — view-объект. Сравнение возвращает False. Для корректного сравнения приведите ключи аннотаций к списку/кортежу или сравнивайте как множества, в зависимости от требований к порядку.

Report Page