zoukankan      html  css  js  c++  java
  • 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__实例化类对象。

  • 相关阅读:
    《从0开始学架构》——学习笔记(基础篇和高性能篇)
    Oracle的数据并发与一致性详解(下)
    Oracle的数据并发与一致性详解(上)
    关于oracle的缓冲区机制与HDFS中的edit logs的某些关联性的思考
    分布式锁的两种实现方式(基于redis和基于zookeeper)
    hadoop配置文件详解系列(二)-hdfs-site.xml篇
    hadoop配置文件详解系列(一)-core-site.xml篇
    【管理心得之四十六】你呀,少肺
    【管理心得之四十五】你呀,没心
    【管理心得之四十四】独立冲突之外,你做不到
  • 原文地址:https://www.cnblogs.com/sddai/p/14215361.html
Copyright © 2011-2022 走看看