• 类对象和对象的创建过程分析


      1 #===============================================
      2 class Mymeta(type): #它是个自定制元类了
      3     def __init__(self): #TypeError: __init__() takes 1 positional argument but 4 were given
      4         pass
      5 
      6 class DemoClass(metaclass=Mymeta):
      7     pass
      8 #这个报错是创建类对象DemoClass时,会将类对象的四部分信息传给Mymeta的__init__,但是它只有一个参数,故报错
      9 
     10 #===============================================
     11 class Mymeta(type): #它是个自定制元类了
     12     def __init__(self,name,bases,dict):
     13         print(self)     #self 是DemoClass 类对象
     14         print(type(self))  #self 的类型是Mymeta
     15         print(name)  #类对象名字
     16         print(bases) #类对象继承的基类
     17         print(dict)  #类对象的属性字典
     18 
     19 class DemoClass(metaclass=Mymeta):
     20     pass
     21 输出:
     22     <class '__main__.DemoClass'>
     23     <class '__main__.Mymeta'>
     24     DemoClass
     25     ()
     26     {'__module__': '__main__', '__qualname__': 'DemoClass'}
     27 
     28 
     29 #===============================================
     30 class Mymeta(type): #它是个自定制元类了
     31     def __init__(self,*args,**kwargs): #也可以用*args和**kwargs同一接收参数
     32         print(self)
     33         print(args) 
     34         print(kwargs)
     35 class DemoClass(metaclass=Mymeta):
     36     pass
     37 '''
     38 <class '__main__.DemoClass'> self
     39 ('DemoClass', (), {'__qualname__': 'DemoClass', '__module__': '__main__'})
     40 {}
     41 '''
     42 #===============================================
     43 此时DemoClass类对象已经创建好了,
     44 如果我们此时执行  DemoClass() 
     45 对象加括号,会调用它的类型中的__call__() 方法,如果它的类中无__call__就会报错:
     46     class Mymeta(type): #它是个自定制元类了
     47         def __init__(self,name,bases,dict):
     48             print("1")
     49 
     50     class DemoClass(metaclass=Mymeta):
     51         def __init__(self,name):
     52             self.name = name
     53 
     54     DemoClass("tom")
     55     没有报错,说明找到了__call__ ,虽然Mymeta中没有,但是在type 中找到了。
     56 #===============================================
     57     class Mymeta(type): #它是个自定制元类了
     58         def __init__(self,name,bases,dict):
     59             print("1")
     60         def __call__(self, *args, **kwargs):
     61             print("2")
     62 
     63 
     64     class DemoClass(metaclass=Mymeta):
     65         def __init__(self,name):
     66             self.name = name
     67 
     68     DemoClass("tom")  #它会调用__call__ 方法
     69     输出: 1,2
     70     现在在Mymeta中找到了__call__,所以就不再去type 中找了,
     71 
     72 #===============================================
     73 其实type 中的__call__是要做三件事的:
     74     创建obj 
     75     然后初始化obj (通过调用它自己的__init__)
     76     然后返回obj 
     77 我们现在在Mymeta中自己的__call__中模拟这个过程:
     78     class Mymeta(type): #它是个自定制元类了
     79         def __init__(self,name,bases,dict):
     80             print("1")
     81         def __call__(self, *args, **kwargs):
     82             print("2")
     83             obj = self.__new__(self)  #类对象DemoClass 调用__new__() ,
     84                 # 首先Mymeta 中没有,于是就去type中找了,那肯定有。然后创建 类对象 (类)的对象
     85             self.__init__(obj,*args,**kwargs) #类对象DemoClass 下的方法
     86             return obj
     87 
     88 
     89     class DemoClass(metaclass=Mymeta):
     90         def __init__(self,name):
     91             self.name = name
     92 
     93     demo = DemoClass("tom")    #它会调用__call__ 方法
     94     print(type(demo))  #返回的是 __new__() 中的参数 即类对象DemoClass
     95 输出是: 
     96     1
     97     2
     98     <class '__main__.DemoClass'>
     99 
    100 #===============================================
    101 #demo 对象的name 属性的赋值过程:
    102 
    103 class Mymeta(type): #它是个自定制元类了
    104     def __init__(self,name,bases,dict):
    105         print("1")
    106     def __call__(self, *args, **kwargs):   #1"tom" 先传到这的args
    107         print("2")
    108         obj = self.__new__(self) 
    109         self.__init__(obj,*args,**kwargs)  #2"tom"再传到这的args
    110         return obj   #4带有"tom"属性的obj 返回
    111 
    112 
    113 class DemoClass(metaclass=Mymeta):
    114     def __init__(self,name):   #3"tom"最后传到这的name
    115         self.name = name
    116 
    117 demo = DemoClass("tom")    #它会调用__call__ 方法
    118 # print(type(demo))  #返回的是 __new__() 中的参数 即类对象DemoClass
    119 
    120 #===============================================
    121 class Mymeta(type): #它是个自定制元类了
    122     def __init__(self,name,bases,dict):
    123         print("1")
    124     def __call__(self, *args, **kwargs):
    125         print("2")
    126         obj = self.__new__(self)  #Mymeta 中没有,type中有  证明如下: 
    127         self.__init__(obj,*args,**kwargs)
    128         return obj
    129 
    130 
    131 class DemoClass(metaclass=Mymeta):
    132     def __init__(self,name):
    133         self.name = name
    134 
    135 demo = DemoClass("tom")    #它会调用__call__ 方法
    136 # print(type(demo))  #返回的是 __new__() 中的参数 即类对象DemoClass
    137 print(type.__dict__)
    138 
    139 type的属性字典:
    140 {'__subclasscheck__': <method '__subclasscheck__' of 'type' objects>, '__dir__': <method '__dir__' of 'type' objects>, '__bases__': <attribute '__bases__' of 'type' objects>, '__name__': <attribute '__name__' of 'type' objects>, '__delattr__': <slot wrapper '__delattr__' of 'type' objects>, '__doc__': <attribute '__doc__' of 'type' objects>, '__dict__': <attribute '__dict__' of 'type' objects>, '__base__': <member '__base__' of 'type' objects>, '__init__': <slot wrapper '__init__' of 'type' objects>, '__sizeof__': <method '__sizeof__' of 'type' objects>, '__instancecheck__': <method '__instancecheck__' of 'type' objects>, 'mro': <method 'mro' of 'type' objects>, '__subclasses__': <method '__subclasses__' of 'type' objects>, '__new__': <built-in method __new__ of type object at 0x000000005913DE40>, '__qualname__': <attribute '__qualname__' of 'type' objects>, '__dictoffset__': <member '__dictoffset__' of 'type' objects>, '__text_signature__': <attribute '__text_signature__' of 'type' objects>, '__abstractmethods__': <attribute '__abstractmethods__' of 'type' objects>, '__weakrefoffset__': <member '__weakrefoffset__' of 'type' objects>, '__setattr__': <slot wrapper '__setattr__' of 'type' objects>, '__module__': <attribute '__module__' of 'type' objects>, '__repr__': <slot wrapper '__repr__' of 'type' objects>, '__itemsize__': <member '__itemsize__' of 'type' objects>, '__prepare__': <method '__prepare__' of 'type' objects>, '__call__': <slot wrapper '__call__' of 'type' objects>, '__getattribute__': <slot wrapper '__getattribute__' of 'type' objects>, '__flags__': <member '__flags__' of 'type' objects>, '__basicsize__': <member '__basicsize__' of 'type' objects>, '__mro__': <member '__mro__' of 'type' objects>}
    141 从这里可以看到这里有__call__方法和__new__ 方法 
    142 
    143 这就是类对象和对象的创建过程分析!
  • 相关阅读:
    人民币格式化 ,分割
    解决IE下页面空白或者报错:[vuex] vuex requires a Promise polyfill in this browser
    js生成图片
    适用于iview的表格转Excel插件
    js金额转大写数字
    webstorm vue cli 热更新不起作用解决办法
    纯css实现 switch开关
    vue 时间戳转 YYYY-MM-DD h:m:s
    Simple2D-20(重构)
    Simple2D-19(音乐播放器)播放器的源码实现
  • 原文地址:https://www.cnblogs.com/zach0812/p/11319560.html
Copyright © 2020-2023  润新知