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
(в нашем случае 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