都说python很容易,可我咋看的这么难,又是装饰器又是MetaClass的。搞得头大,那么什么是MetaClass,首先,我们要搞清楚python中有两中关系,issubclass和isinstance。issubclass用于判断一个类是否是一个类的父类。isinstance用于判断一个对象是否是一个类的实例。
MetaClass最基本的类就是type。可以用它来创建一个新的类A,此时这个新的类A就是type的一个实例isinstance(A,type)为真。因此,MetaClass主要用来创建类,并可以对新的类进行修改。我们对下面的代码进行一个解析。
class MyMeta(type):
def __new__(cls, *args, **kwargs):
print(1)
print(cls)
print('===>MyMeta.__new__')
print(cls.__name__)
return super().__new__(cls, *args, **kwargs)
def __init__(self, classname, superclasses, attributedict):
super().__init__(classname, superclasses, attributedict)
print(self)
print('===>MyMeta.__init__')
print(self.__name__)
print(classname)
print(superclasses)
print(attributedict)
print(self.tag)
print(2)
def __call__(self, *args, **kwargs):
print('===>MyMeta.__call__')
print(self)
obj = self.__new__(self, *args, **kwargs)
self.__init__(self, *args, **kwargs)
print(3)
return obj
class Foo(object, metaclass=MyMeta):
tag = '!Foo'
print(5)
def __new__(cls, *args, **kwargs):
print('===>Foo.__new__')
print(6)
print(cls)
return super().__new__(cls)
def __init__(self, name):
print(self)
print('===>Foo.__init__')
self.name = name
print(7)
print('test start')
foo = Foo('test')
print('test end')
结果为
5
1
<class '__main__.MyMeta'>
===>MyMeta.__new__
MyMeta
<class '__main__.Foo'>
===>MyMeta.__init__
Foo
Foo
(<class 'object'>,)
{'__module__': '__main__', '__qualname__': 'Foo', 'tag': '!Foo', '__new__': <function Foo.__new__ at 0x000001AF0F1D6B80>, '__init__': <function Foo.__init__ at 0x000001AF0F1D6A60>, '__classcell__': <cell at 0x000001AF0F1D8CA0: MyMeta object at 0x000001AF0EADAAF0>}
!Foo
2
test start
===>MyMeta.__call__
<class '__main__.Foo'>
===>Foo.__new__
6
<class '__main__.Foo'>
<class '__main__.Foo'>
===>Foo.__init__
7
3
test end
首先内存先加载MyMeta,加载__new__,init,__call__方法。然后继续加载Foo类,此时会首先输出5。然后metaclass=MyMeta告诉编译器,Foo类的MetaClass是MyMeta,因为Foo是MyMeta的一个实例,在创建实例时,会首先调用__new__方法,此时输出1,cls就是MyMeta类,args里是Foo类的信息。然后调用__init__方法,self就是Foo,classname为Foo的类名,superclasses为Foo的父类元组,attributedict为Foo类的属性信息字典。然后输出2.接着运行test start,创建Foo的实例,而Foo是MyMeta的实例,因此Foo()会调用MyMeta的__call__方法,此时self为Foo这个实例,则在__call__方法中又会调用Foo的__new__方法先输出6,然后调用Foo的__init__方法输出7.最后输出3.最后输出test end.
由次可见,对于Foo方法,可在MyMeta中的__init__中的attributedict修改Foo的属性,当然,__new__方法也可以。综上,MetaClass就是一个用来创建类的类,与创建的类属于isinstance的关系。
版权声明:本文为weixin_42834523原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。