元类

class Foo:
    pass
f1 = Foo()
print(type(f1))          #打印实例的类型,结果是<class '__main__.Foo'>
print(type(Foo))         #打印类的类型,结果是<class 'type'>


"""
元类:是类的类,是类的模板
    元类是控制如何创建类的,就像用类创建实例一样,类就是元类的实例化对象
    type是Python中的一个内建元类,用来控制生成类,Python中任何class定义的类都是默认type元类的实例化对象
"""

#利用type生成一个类,得到的结果和class生成的一样
def __init__(self,name,age):      #先定义类中的属性
    self.name = name
    self.age = age
def test(self):
    print("it is test")
Bar = type("Bar",(object,),{"x":1,"__init__":__init__,"test":test})    #类的属性放在第三个参数的字典中
print(Bar)
print(Bar.__dict__)
b1= Bar("ss",22)
print(b1.name)
b1.test()
#自定义元类
class MyType(type):
    def __init__(self,a,b,c):   #4个参数,self,生成的类名,继承的父类(用于继承的情况,可为空),属性字典
        print("元类的构造函数执行")
        print(a)            #代表下面继承元类的类名Myclass
        print(b)
        print(c)

    def __call__(self, *args, **kwargs):     #self是实例本身,这里就是下面的元类的实例Myclass
        print("=====>")
        obj = object.__new__(self)          #object.__new__(Myclass)--->产生Myclass的实例m1
        self.__init__(obj,*args,**kwargs)   #Myclass.__init__(),就是在调用下面的Myclass的__init__属性
        return obj

class Myclass(metaclass=MyType):   #MyType(self,"Myclass",(),{})--->触发__init__
    def __init__(self,name):
        self.name =name

print(Myclass)
m1 = Myclass("ss")      #触发自定义元类中的__call__,得到call里的返回值,需要在call中定义init,使其自动触发init属性
print(m1)

 

posted @ 2019-05-17 22:44  saber゛  Views(198)  Comments(0Edit  收藏  举报