Коротко о задаче

Коротко о задаче

@python_quiz

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

Имеется фрагмент Python-кода с множественным наследованием. Нужно понять, какая реализация метода f() будет вызвана при создании экземпляра D и вызове D().f().

Исходный код

python

Что делает код

  • A задаёт базовую реализацию f(), возвращающую 'A'.
  • B наследует A, но не переопределяет f().
  • C наследует A и переопределяет f(), возвращая 'C'.
  • D наследует одновременно от B и C (в указанном порядке B, C).

При вызове D().f() интерпретатор ищет метод по порядку, определённому MRO (method resolution order).

Разбор MRO (порядка поиска методов)

Python использует алгоритм C3-линеаризации для вычисления MRO при множественном наследовании. Для данного класса D порядок будет такой:

  • D
  • B
  • C
  • A

Можно проверить это прямо в интерпретаторе:

python

Ожидаемый вывод:

python

Поэтому при поиске f() Python смотрит в D → B → C → A. В B метода f нет, в C есть — он и будет вызван.

Демонстрация результата

python

Анализ вариантов (куда бы могло вести заблуждение)

  • "A": подошло бы, если бы C не переопределял f и ни в B, ни в C не было реализации отличной от A. Но здесь C содержит своё f(), и оно находится раньше A в поиске.
  • "B": возможно подумать, что раз B стоит первым в списке базовых классов D(B, C), то выбор будет за B. Но B не определяет f(), поэтому поиск продолжается дальше — в C, где метод найден.
  • "C": корректно — C содержит реализацию f(), и она обнаруживается при обходе MRO.
  • "TypeError из-за конфликта MRO": возник бы при некорректной или неоднозначной иерархии наследования (например, если бы алгоритм C3 не смог построить допустимую линейную последовательность). В данном случае иерархия согласована, конфликтов нет.

Небольшой бонус — что если оба подкласса реализуют метод

Если и B, и C определят f(), то при D(B, C) будет выбрана реализация из B (левый приоритет):

python

Вывод

В рассматриваемом коде поиск метода следует порядку MRO D → B → C → A. Поскольку B не содержит f(), а C содержит, будет вызвана реализация из C и программа выведет строку 'C'.

Report Page