Выбор ответа Senior Типизация обновлено
Инвариантность list
Вопрос
Почему mypy не разрешает передать list[Dog] в функцию с параметром animals: list[Animal] (Dog наследует Animal)?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: list инвариантен: в список собак можно добавить Cat. Изменяемый контейнер инвариантен: если бы list[Dog] считался list[Animal], функция могла бы сделать animals.append(Cat()), и у вызывающего в списке собак оказалась бы кошка.
Варианты ответа
- mypy не поддерживает наследование классов в дженериках
- Нужно явно привести тип через
cast(list[Animal], dogs) - Списки нельзя передавать в функции с аннотациями
listинвариантен: в список собак можно добавитьCatправильный ответ
Разбор
Изменяемый контейнер инвариантен: если бы list[Dog] считался list[Animal], функция могла бы сделать animals.append(Cat()), и у вызывающего в списке собак оказалась бы кошка. Если функция только читает, тип параметра делают Sequence[Animal] или Iterable[Animal], они ковариантны, и list[Dog] подходит. cast прячет проблему, а наследование mypy поддерживает.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.