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'}

 

posted @ 2018-11-04 21:23  Meanwey  阅读(497)  评论(0编辑  收藏  举报