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

  • 相关阅读:
    错误C2665: “AfxMessageBox”: 2 个重载中没有一个可以转换所有参数类型
    为什么DW的可视化下看到的效果与浏览器的效果有所区别?
    font-family:黑体;导致css定义全部不起作用
    web标准中定义id与class有什么区别吗
    网页尺寸规范
    SEO为什么要求网页设计师用DIV+CSS布局网页?
    去掉CSS赘余代码,CSS可以更简洁
    解决IE6、IE7、Firefox兼容最简单的CSS Hack
    实战中总结出来的CSS常见问题及解决办法
    高效整洁CSS代码原则 (下)
  • 原文地址:https://www.cnblogs.com/sddai/p/14215361.html
Copyright © 2011-2022 走看看