Python中创建对象的内部流程、metaclass和type类
原文:https://blog.csdn.net/m0_37519490/article/details/80825934
一、metaclass干嘛的?
metaclass是指定类由谁创建。能够定制类的创建过程
指定类由谁创建的???开什么玩笑,类不是由'我'创建的吗????
python中一切皆对象,类也是对象,类是由type类创建。
我们写下如下代码时:
class Foo(object): pass
实际上,解释器将其解释为:
Foo = type('Foo', (object,), {})
type()的三个参数:'Foo':类名; (object, ): 类的继承关系,用元组表示; {}: 类的字段,方法。
以上是类的默认创建方法。由type创建。python也给我们提供了自定义类的创建的方法,即metaclass。type也是类,它可以创建类,因此我们叫它元类,不要过分纠结这是什么鬼,知道type类可以创建类就行。
自定义类的创建过程,那就得写一个像type一样可以创建类的类,那简单,继承就可以办到。
方式一:
class MyType(type): def __new__(cls, *args, **kwargs): print('MyType __new__') return super().__new__(cls, *args, **kwargs) def __init__(cls, *args, **kwargs): print('MyTpye __init__') super().__init__(*args, **kwargs) def __call__(cls, *args, **kwargs): print('MyTpye __call__') super().__call__(cls, *args, **kwargs) class Foo(metaclass=MyType): pass
这样,解释器解释到class Foo(...)的时候,就会转换为:
Foo = MyType('Foo', (object,), {})
方式二:
class MyType(type): def __new__(cls, *args, **kwargs): print('MyType __new__') return super().__new__(cls, *args, **kwargs) def __init__(cls, *args, **kwargs): print('MyTpye __init__') super().__init__(*args, **kwargs) def __call__(cls, *args, **kwargs): print('MyTpye __call__') super().__call__(cls, *args, **kwargs) def with_meta(meta, Base): return meta('Foo', (Base, ), {}) class Foo(with_meta(MyType, object)): pass
这样解释的时候,与方式一的一样。
二、创建类与类实例化时执行过程是怎样的?
解释器解释到class的定义语句时,会先在class中寻找是否指定自定义的'MyType', 没有再往父类找是否指定,没有再在本模块中找,是否本模块指定了统一的'MyType', 若均没有,则用默认的type创建。
解释到class Foo(...)时,会调用'MyType'的__new__, __init__方法。生成类。
解释到f = Foo() ,类的实例化时,会调用'MyType'的__call__方法,而'type'的__call__方法又会去调用Foo的__new__, __init__实例化类对象。
如果这篇文章帮助到了你,你可以请作者喝一杯咖啡