Переопределение __init__ в метаклассе Python 3.8
Всем привет! Есть код..
class MyMetaClass(type):
def __new__(cls, name, bases, attr):
NewName = name+'new_name'
attr['new_attr'] = 'new_value'
NewClass = super().__new__(cls, NewName, bases, attr)
return NewClass
def __init__(cls, name, bases, attr):
name = 'TEST'
attr['new_attr_init'] = 'new_value_init'
super().__init__(name, bases, attr)
class MyClass(metaclass = MyMetaClass):
MyClassField = 'My_value'
def __init__(self, x):
self.x = x
obj = MyClass(777)
Три вопроса.
- Почему в метод __init__ метакласса в качестве аргумента не передается новое имя класса (name), измененное в __new__. Переменная name после входа в функцию __init__ такая же, как и при входе в __new__. Передаются ссылки на аргументы входа в __new__?
- Почему при изменении, как имени класса, так и атрибутов в методе __init__ и передаче их в
super().__init__(name, bases, attr)это не отражается на инициализиции и изменении класса. Атрибутnew_attr_initсо своим значениемnew_value_initне попадает в словарь инициализированного класса. Такое изменение атрибутов происходит только в __new__. А изменить существующий атрибут, например MyClassField, можно написав в том же методе __init__cls.MyClassField = 'New_Value', не используяsuper().__init__(name, bases, attr). - Зачем тогда вообще в метаклассах в переопределенном __init__ и вызывают
super().__init__(name, bases, attr), тогда как это не на что не влияет.
Ответы (1 шт):
Автор решения: n1tr0xs
→ Ссылка
Вот так надо по идее:
class MyMetaClass(type):
def __new__(cls, name, bases, attr):
NewName = name+'new_name'
attr['new_attr'] = 'new_value'
NewClass = super().__new__(cls, NewName, bases, attr)
if isinstance(NewClass, cls):
super().__init__(NewClass, NewName, bases, attr)
return NewClass
def __init__(cls, name, bases, attr):
name = 'TEST'
attr['new_attr_init'] = 'new_value_init'
class MyClass(metaclass = MyMetaClass):
MyClassField = 'My_value'
def __init__(self, x):
self.x = x
obj = MyClass(777)