它的做用主要是 指定由誰來建立類,默認是typepython
#python3 class Foo(metaclass=MyType): pass #python2 class Foo(object): __metaclass__ = MyType
注意下面的代碼中的運行結果,若是某個基類執行誰來建立,那麼繼承這個基類的派生類也由這個誰來建立函數
class MyType(type): def __init__(self,*args,**kwargs): print('init') super(MyType, self).__init__(*args, **kwargs) def __call__(self, *args, **kwargs): print('call本質:調用類的__new__,在調用init方法') return super(MyType, self).__call__(*args, **kwargs) class Foo(metaclass=MyType): def __call__(self, *args, **kwargs): print('123') class Bar(Foo): pass Foo() #實例化對象,會執行負責建立類的type裏的__call__方法 obj = Bar() obj() #對象+() 執行父類的裏__call__方法
應該見過這樣建立類的吧,經過type建立Base = type('Base', (object,), {})spa
因此咱們經過繼承type的自定義type類也是能夠這麼作的Base = MyType('Base', (object,), {}),那這個過程本質也就是和上面metaclass同樣的效果,指定了MyType進行建立類對象
class MyType(type): def __init__(self, *args, **kwargs): super(MyType, self).__init__(*args, **kwargs) def __call__(cls, *args, **kwargs): print('xxxx') return super(MyType, cls).__call__(*args, **kwargs) # Base = MyType('Base', (object,), {}) # MyType('Base', (object,), {}) 是有MyType建立; metaclass=MyType # 1. type能夠建立類metaclass=type;MyType也能夠建立類metaclass=MyType # 2. Base = MyType('Base', (object,), {}) --> # class Base(metaclass=MyType): # pass # class Foo(Base): # pass class Foo(MyType('Base', (object,), {})): pass obj = Foo()
因此這個Foo繼承的是MyType建立的類,而Foo子類也會由MyType進行建立,彷佛這種方式看起更簡潔blog
不過把建立Base類型整個過程都寫在Foo繼承上,不免有些看着有些糟心,另外base執行繼承類也是寫死了,咱們可獨立出一個函數進行封裝,並動態實現傳入繼承類繼承
class MyType(type): def __init__(self, *args, **kwargs): super(MyType, self).__init__(*args, **kwargs) def __call__(cls, *args, **kwargs): return super(MyType, cls).__call__(*args, **kwargs) def with_metaclass(base): return MyType('XX', (base,), {}) class Foo(with_metaclass(object)): pass