Python进阶-----元类及自定制元类
一、什么是元类
元类:就是生成类的的类,或者说是类的模版。
1 #定义一个类来看一下 2 class Meanwey: 3 pass 4 m = Meanwey() 5 6 #通过type来查看对象的类 7 print(type(m)) #<class '__main__.Meanwey'> m这个对象是属于Meanwey这个类 8 9 #类本身也是对象,所以可以用type来查看 10 print(type(Meanwey)) #<class 'type'> Meanwey这个类对象属于type这个类
通过上述简单代码可以看到,默认元类就是type。
二、所以可以用type这个元类来生成类
语法:想要生成的类名 = type(想要生成的类名,(继承的类默认objec,),属性字典{'x':1})。
注意:type中有三个参数,第一个参数是想要生成的类名为字符串类型;第二个参数是继承的类默认为obje为元组类型;第三个参数为生成的类的属性字典为字典类型。
1 Meanwey = type('Meanwey',(object,),{'name':'Meanwey'}) 2 m1 = Meanwey() 3 print(type(m1)) #<class '__main__.Meanwey'> 4 print(type(Meanwey)) #<class 'type'> 5 6 # 可以看到通过type来生成的类和class关键字生成的类一样 7 # 当然也可以给类添加函数(方法)属性,则需要在type语句前先定义好函数(方法),然后在type的第三个参数添中加上函数属性和函数名 8 9 def __init__(self,name,age): #添加构造函数 10 self.name = name 11 self.age = age 12 def test(self): 13 print('调用了test方法') 14 15 Meanwey = type('Meanwey',(object,),{'name':'Meanwey','__init__':__init__,'test':test}) #加上函数属性 16 m1 = Meanwey('小明同学',24) #因为上面定义了构造函数__init__需要name,age两个参数,所以在实例化的时候需要传入 17 # print(type(m1)) #<class '__main__.Meanwey'> 18 # print(type(Meanwey)) #<class 'type'> 19 20 #查看初始化构造函数是否成功 21 print(m1.__dict__) #{'name': '小明同学', 'age': 24} 22 23 #调用test函数 24 m1.test() #调用了test方法
三、自定制元类
一个类没有声明自己的元类,默认他的元类就是type,除了使用内置元类type,我们也可以通过继承type来自定义元类,然后使用metaclass关键字参数为一个类指定元类。
1 #自定义元类 2 class Meta_Type(type): 3 def __call__(self,*args,**kwargs): 4 5 #self是Meta_Type的实例,也就是Foo 6 #因为每个类都默认继承object,所以可以调用__new__(Foo)方法,来实例化一个对象f1 == object.__new__(Foo) ==> f1 7 obj = object.__new__(self) 8 9 #调用Foo的构造函数实例化对象 == Foo.__init__(f1,*args,**kwargs) 10 self.__init__(obj,*args,**kwargs) 11 12 #最后要返回f1这个对象 13 return obj 14 15 #metaclass = Meta_Type ====> 会触发Foo = Meta_Type(Foo,'Foo',(),{}) ===>会触发Meta_Type的 __init__ 16 class Foo(metaclass=Meta_Type): 17 def __init__(self,name): 18 self.name = name 19 20 #当Foo()时,表示执行了Foo,则会调用元类的__call__,__call__中会生成对象f1,并且调用Foo下的__init__方法,最终完成实例化 21 f1 = Foo('Menawey') 22 23 #>>>我是元类 24 25 print(f1.__dict__) 26 #>>>{'name': 'Menawey'}