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

  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 这就是类对象和对象的创建过程分析!

猜你喜欢

转载自www.cnblogs.com/zach0812/p/11319560.html