zoukankan      html  css  js  c++  java
  • 2019年10月4日 元类

    metaclass 元类

    元类是类的类,是类的模版。

    元类是用来控制如何创建类的,正如类是创建对象的模版一样

    元类的实例为类。

    type事python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象。

    class Foo:
        pass
    
    f1=Foo() #f1是通过Foo类实例化的对象
    print(type(f1))#用type函数查看是谁的类
    print(type(Foo))#类的类就是type
    
    
    def __init__(self,name,age):#如果需要再type中增加构造函数,就需要将函数放到最外面
        self.name=name
        self.age=age
    FFo=type('FFo',(object,),{'x':1,'__init__':__init__}) #用type生成类,第一个事类名,第二个元祖形式是父类,因为是新式类所以父类默认就是object,后面是用字典形式表达参数
    print(FFo)
    f1=FFo('SXJ',11)
    print(f1.__dict__)

    >>>>

    <class '__main__.Foo'>
    <class 'type'>
    <class '__main__.FFo'>
    {'name': 'SXJ', 'age': 11}

    可以通过继承type来自定义元类。

    class MyType(type): #定义元类
        def __init__(self,a,b,c):
            print('元类构造函数执行')
            print(self,'
    ',a,'
    ',b,'
    ',c) #self 就是元类mytype的实例,也就是Foo
    
        def __call__(self, *args, **kwargs):
            print('>>>>>')
            print(self)
            print(args,kwargs)
            obj=object.__new__(self) #创建一个新对象 objcet.__new__(Foo) 这一步就是产生F1的
            self.__init__(obj,*args, **kwargs)# 就是在调用Foo.__init__()把Foo内的init中的参数原封不动的传过去
            print(obj)
            return obj #返回值赋予给F1
    
    class Foo(metaclass=MyType):#声明元类 Foo=Mytype('Foo',(object,),{'name':name}),传递了4个参数给Mytype,触发init方法,所以mytype中的init需要4个参数
        def __init__(self,name):
            self.name=name #f1.name=name
    
    f1=Foo('sxj') #实例化会触发init 和call
    print(f1.__dict__)

    >>>>

    元类构造函数执行
    <class '__main__.Foo'>
    Foo
    ()
    {'__module__': '__main__', '__qualname__': 'Foo', '__init__': <function Foo.__init__ at 0x10219d0d0>}

    >>>>>
    <class '__main__.Foo'>
    ('sxj',) {}
    <__main__.Foo object at 0x102176f98>
    {'name': 'sxj'}

    精简版

    class MyType(type): #定义元类
        def __init__(self,a,b,c):
            print('元类构造函数执行')
        def __call__(self, *args, **kwargs):
            obj=object.__new__(self) #创建一个新对象 objcet.__new__(Foo) 这一步就是产生F1的
            self.__init__(obj,*args, **kwargs)# 就是在调用Foo.__init__()把Foo内的init中的参数原封不动的传过去
            return obj #返回值赋予给F1
    
    class Foo(metaclass=MyType):#声明元类 Foo=Mytype('Foo',(object,),{'name':name}),传递了4个参数给Mytype,触发init方法,所以mytype中的init需要4个参数
        def __init__(self,name):
            self.name=name #f1.name=name
    
    f1=Foo('sxj') #实例化会触发init 和call
  • 相关阅读:
    上周热点回顾(12.1212.18)
    上周热点回顾(11.2111.27)
    上周热点回顾(11.1411.20)
    博客园电子期刊2011年11月刊发布啦
    “CDN加速”测试
    上周热点回顾(11.2812.4)
    上周热点回顾(12.1912.25)
    上周热点回顾(12.512.11)
    提醒:安装MS11100 .NET Framework高危漏洞补丁一定要所有服务器一起安装
    郑州公积金
  • 原文地址:https://www.cnblogs.com/python1988/p/11623105.html
Copyright © 2011-2022 走看看