• 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'}
  • 相关阅读:
    html 的一些基础操作
    java 通过反射调用属性,方法,构造器
    java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包
    java 反射,类的加载过程以及Classloader类加载器
    java 随机读写访问流及seek方法
    java 序列化机制
    java 标准输入输出流,打印流,数据流
    hp400 硒鼓加粉图解
    Delphi XE5 android 获取网络状态
    Delphi XE5 常见问题解答
  • 原文地址:https://www.cnblogs.com/Meanwey/p/9905937.html
Copyright © 2020-2023  润新知