Fork me on GitHub

Python中创建对象的内部流程、metaclass和type类

 

obj = Foo()的执行流程
第一阶段:编译器执行到class Foo(object)时:
1. class Foo 执行,由于metaclass=MyType,所以先执行MyType的__init__方法
2. 这时,obj是一个Foo类的对象,Foo类本身又是MyType类的对象(如果不指定metaclass=MyType,则默认metaclass是系统内置的Type类)
3. MyType的__init__方法调用父类type类的init方法,第一阶段结束
第二阶段:编译器执行到obj = Foo() 时:
4. Foo是一个类,python中一切皆对象,Foo可以看成是MyType类的一个对象,因此,Foo()可以看成以对象名调用了MyType类的__call__方法,所以接下来执行MyType类的__call__方法
5. MyType类的__call__方法调用Foo类(这里就是self)的__new__方法,以及__init__方法
6. 真正创建对象是Foo中的__new__方法调用的object.__new__
7. 这里的self指代Foo,然后执行self.__init__

 


原文: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__实例化类对象。

 

posted @ 2020-12-31 11:30  stardsd  阅读(738)  评论(1编辑  收藏  举报