Sobes.tech
Назад к вопросам
Junior — Middle
56

Какие вызовы методов метакласса происходят в процессе определения нового класса?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

При определении класса Python сначала вызывает метакласс для создания самого объекта класса, а затем может отдельно инициализировать этот объект. Обычно это сводится к вызовам __prepare__, __new__ и __init__ метакласса. Понимание этого важно, чтобы объяснить, как Python строит класс из тела class.

Определение:

При выполнении инструкции class Python использует метакласс, чтобы собрать пространство имён класса, создать объект класса и затем его инициализировать. Типичный порядок такой: сначала metaclass.__prepare__, затем выполнение тела класса, потом metaclass.__new__, после этого metaclass.__init__. Если метакласс не задан явно, обычно используется type.

Пример использования:

class Meta(type):
    @classmethod
    def __prepare__(mcls, name, bases):
        print("prepare", name)
        return {}

    def __new__(mcls, name, bases, namespace):
        print("new", name, namespace)
        return super().__new__(mcls, name, bases, namespace)

    def __init__(cls, name, bases, namespace):
        print("init", name)
        super().__init__(name, bases, namespace)


class User(metaclass=Meta):
    x = 10

    def greet(self):
        return "hi"

Пояснение кода:

В этом примере при создании User сначала вызывается Meta.__prepare__, чтобы получить словарь для тела класса. Затем Python выполняет тело class User, и в namespace попадают x и greet. После этого вызывается Meta.__new__, где уже видно собранное содержимое класса, и создаётся объект класса. В конце вызывается Meta.__init__, который завершает инициализацию уже созданного класса.

Ключевые моменты:

  • __prepare__ вызывается первым и возвращает mapping для тела класса.
  • Тело class выполняется между __prepare__ и __new__.
  • __new__ метакласса создаёт объект класса.
  • __init__ метакласса инициализирует уже созданный класс.
  • Если метакласс не указан, используется стандартный type.
  • На собеседовании важно различать создание экземпляра класса и создание самого класса.