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将在MyMeta
的类型(在我们的情况下是type
)中查找__call__
。
"对于新式类,只有在对象的类型中定义了特殊方法,而不是在对象的实例字典中定义的,才能保证隐式调用特殊方法正常工作"
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)
将为MyClass
设置正确的元类(即MyMeta
)。
type(cls, bases, attributes)
将为MyClass
设置默认的元类(即type)。
class A(object, metaclass=MetaA): pass
。在类A作用域中的__metaclass__
完全被忽略。 - Mr_and_Mrs_D