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,'\n',a,'\n',b,'\n',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

 

转载于:https://www.cnblogs.com/python1988/p/11623105.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值