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