Метакласс, namespace и наследование в Python
@python_quizРазберем этот квиз
Коротко: у нас есть метакласс, который в своём __new__ добавляет атрибут x в пространство имён создаваемого класса. Одновременно у нас есть базовый класс Base с собственным x. Вопрос — какие значения будут у Base.x и Child.x, и будет ли экземпляр Child считаться экземпляром Base.
Условие (код)

Как это работает — по шагам
- type('Base', (), {'x': 1}) создаёт класс Base обычным способом (метакласс — type). У класса Base в атрибутах хранится
x = 1. - При создании Child вызывается метакласс Meta:
- Python формирует namespace (ns) для нового класса. В данном случае ns — пустой словарь, потому что {} передали при создании.
- Вызывается Meta.__new__(mcls, name, bases, ns). Внутри __new__ код добавляет ns['x'] = 10 — то есть атрибут x добавляется в namespace будущего класса Child.
- Затем super().__new__ создаёт сам объект класса Child, используя уже дополненный словарь ns.
- В результате:
- Base.x остаётся 1, потому что мы не меняли класс Base.
- Child.x равно 10 — атрибут определён прямо в классе Child.
- Child наследует от Base, поэтому isinstance(Child(), Base) возвращает True (наследование сохраняется).
Выполнение и вывод
Если запустить приведённый код, он выведет:

Пояснения:
- Первый элемент — Base.
x = 1. - Второй — Child.
x = 10. - Третий — True, потому что Child является подклассом Base, и экземпляр Child — экземпляр Base.
Разбор вариантов (почему другие ответы не подходят)
- "1 10 False" — неверно, потому что хотя значения x у Base и Child установлены как 1 и 10, экземпляр Child всё же является экземпляром Base из-за наследования.
- "10 10 True" — неверно, потому что Base.x не изменялся метаклассом при создании Child; Base.x остался 1.
- "10 1 True" — неверно, потому что Child.x получил значение 10 в своём классовом namespace, а Base.x был 1.
Выводы и полезные наблюдения
- Метакласс получает namespace каждого создаваемого класса отдельно. Изменения делаются в namespace конкретного класса, а не в его базах.
- Использование метакласса позволяет программно добавлять или менять атрибуты классов при их создании.
- Наследование классов и поведение isinstance зависят от иерархии классов (bases), а не от того, какие атрибуты добавлены метаклассом.
Если нужно, можно расширить пример: показать, как метакласс может модифицировать bases, добавить методы, или как отличить действия в __new__ и __init__ метакласса.