class MyMeta(type):
def __new__(meta, cls, bases, attributes):
print 'MyMeta.__new__'
return type.__new__(meta, cls, bases, attributes)
def __init__(clsobj, cls, bases, attributes):
print 'MyMeta.__init__'
class MyClass(object):
__metaclass__ = MyMeta
foo = 'bar'
Другой способ достижения тот же результат:
cls = "MyClass"
bases =()
attributes = {'foo': 'bar'}
MyClass = MyMeta(cls, bases, attributes)
MyMeta
является вызываемым, поэтому Python будет использовать специальный метод __call__
.
Python будет искать __call__
в MyMeta
«s тип (который type
в нашем случае)
«Для новых классов, неявных вызовов специальных методов только гарантированно работать правильно, если они определены по типу объекта, а не в словаре экземпляра объекта»
MyClass = MyMeta(...)
интерпретируется как:
my_meta_type = type(MyMeta)
MyClass = my_meta_type.__call__(MyMeta, cls, bases, attributes)
Внутри type.__call__()
я представляю себе что-то вроде этого:
MyClass = MyMeta.__new__(MyMeta, cls, bases, attributes)
meta_class = MyClass.__metaclass__
meta_class.__init__(MyClass, cls, bases, attributes)
return MyClass
MyMeta.__new__()
будет решить, как MyClass
построен:
type.__new__(meta, cls, bases, attributes)
установит правильный метакласса (который MyMeta
) для MyClass
type(cls, bases, attributes)
установит метакласс по умолчанию (который является типом) для MyClass
Но это вопрос, на который я обращаюсь: почему «type» не возвращает правильный тип объекта? Я знаю, что мне нужно использовать метод '__new__' подкласса, но как это отличается от использования' type'? –
Как тип должен магически знать, какого объекта вы хотите его создать? –
хорошо, потому что я говорю. Я передал имя, базы и диктофон. Какую еще часть информации мне нужно дать? –