zoukankan      html  css  js  c++  java
  • 深入解析类对象与类实例的创建过程

    
    
    class MyType(type):
    def __init__(self,*args,**kwargs):
    print("init")
    super(MyType, self).__init__(*args,**kwargs)

    def __new__(cls, *args, **kwargs):
    print("new")
    print("mro",cls.__mro__)
    # 调用父类的__new__ 方法来实例出一个Base类对象
    return super(MyType, cls).__new__(cls, *args, **kwargs)

    def __call__(self, *args, **kwargs):
    # self = Base类对象
    # 调用object类的__new__方法,创建Base的实例对象
    obj = object.__new__(self)
    # 执行 构造方法
    obj.__init__()
    print('obj',obj)
    return obj


    class Base(metaclass=MyType):
    def __init__(self):
    print("Base init")

    def __new__(cls, *args, **kwargs):
    ret = super(Base, cls).__new__(cls, *args, **kwargs)
    print("Base ret",ret)
    return ret

    a = Base()
    print(a,'a的返回值')

      Base是一个对象,Base()则调用创建该类的__call__方法。执行__call__方法本质上是首先执行Base类中的__new__方法,然后再执行__init__方法,最终将生成的经过初始化的实例对象返回给a。也就是说,__call__方法的返回值是什么,生成的实例对象就是什么。需要注意的是,在__call__方法中,self指的是Base对象,因此 obj = object.__new__(self) 生成的是Base类的对象, obj.__init__() 执行的是Base的__init__方法,至此完成了创建Base类实例的过程。

      需要说明的是,我在元类的__call__方法中以手动的方式执行 __new__和__init__,但也可以用  super(MyType, self).__call__(*args, **kwargs) 完成相同的效果,这里只是为了说明   super(MyType, self).__call__(*args, **kwargs) 的内部执行流程。

    super补充

      首先要明确的是,super是一个类,不是一个函数。以 super(MyType, self).__call__(*args, **kwargs) 为例,super(cls,ins)获得是cls在ins的mor表中的下一个类对象,再通过该对象调用该对象下的__call__方法,如果此类中没有__call__方法,那么再按照ins的mro表继续向下查找,无论如何,一定可以在object类中找到__call__方法,在__call__方法中首先创建一个cls的实例,然后执行该实例的__init__方法,从而完成cls类的实例。

     
  • 相关阅读:
    POJ 3114 Tarjan+Dijkstra
    278. First Bad Version
    209. Minimum Size Subarray Sum
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    710. Random Pick with Blacklist
    767. Reorganize String
    524. Longest Word in Dictionary through Deleting
    349. Intersection of Two Arrays
    350. Intersection of Two Arrays II
  • 原文地址:https://www.cnblogs.com/liuyinzhou/p/9728369.html
Copyright © 2011-2022 走看看