2. Напиши метакласс, который запрещает классам-наследникам переопределять метод do_not_override, если он есть в базовом классе.

В __new__ метакласса проверяйте namespace нового класса: если он объявляет do_not_override, а метод уже есть у базового класса, выбрасывайте TypeError до создания класса.

Короткий ответ

Что ответить на собеседовании

В new метакласса проверяйте namespace нового класса: если он объявляет do_not_override, а метод уже есть у базового класса, выбрасывайте TypeError до создания класса.

Подробный разбор

Ответ с пояснениями

Условие

2. Напиши метакласс, который запрещает классам-наследникам переопределять метод do_not_override, если он есть в базовом классе.

Ответ

В new метакласса проверяйте namespace нового класса: если он объявляет do_not_override, а метод уже есть у базового класса, выбрасывайте TypeError до создания класса.

Минимальный вариант проверяет переопределение при объявлении наследника:

class NoOverride(type):
    def __new__(mcls, name, bases, namespace, **kwargs):
        inherited = any(hasattr(base, 'do_not_override')
                        for base in bases)
        if inherited and 'do_not_override' in namespace:
            raise TypeError('do_not_override is final')
        return super().__new__(mcls, name, bases, namespace, **kwargs)

class Base(metaclass=NoOverride):
    def do_not_override(self):
        return 'fixed'

Проверка учитывает метод, унаследованный базой от более дальнего предка. Она не защищает от последующего monkey patching или затенения через сложное множественное наследование; для такого расширенного контракта нужны дополнительные проверки. Это ограничение API, не граница безопасности.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее