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 这就是类对象和对象的创建过程分析!
原文:https://www.cnblogs.com/zach0812/p/11319560.html