Выбор ответа Senior Типизация обновлено

Инвариантность list

Вопрос

Почему mypy не разрешает передать list[Dog] в функцию с параметром animals: list[Animal] (Dog наследует Animal)?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: list инвариантен: в список собак можно добавить Cat. Изменяемый контейнер инвариантен: если бы list[Dog] считался list[Animal], функция могла бы сделать animals.append(Cat()), и у вызывающего в списке собак оказалась бы кошка.

Варианты ответа

  1. mypy не поддерживает наследование классов в дженериках
  2. Нужно явно привести тип через cast(list[Animal], dogs)
  3. Списки нельзя передавать в функции с аннотациями
  4. list инвариантен: в список собак можно добавить Catправильный ответ

Разбор

Изменяемый контейнер инвариантен: если бы list[Dog] считался list[Animal], функция могла бы сделать animals.append(Cat()), и у вызывающего в списке собак оказалась бы кошка. Если функция только читает, тип параметра делают Sequence[Animal] или Iterable[Animal], они ковариантны, и list[Dog] подходит. cast прячет проблему, а наследование mypy поддерживает.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.