元类的概念
元类是类的类,是类的模板
元类是用来控制如何创建类的,正如类是创建对象的模板一样
元类的实例是类,正如类的实例为对象
type是python的一个内建元类,用来直接控制生成类,python中class定义的类其实都是type类实例化的对象
产生类的两种方式
类的产生有两种方式,这两种方式产生的类的本质是一样的
class Foo:
x = 1
FFo = type("FFo", (object,), {"x": 1})
print(Foo)
print(FFo)
如果一个类没有声明自己的元类,默认它的元类就是type,除了使用type,用户也可以通过继承来自定义元类
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
x = 1
def __init__(self, name, age):
self.name = name
self.age = age
FFo = type("FFo", (object,), {"x": 1, "__init__": __init__})#三个参数分别是 类名 、继承的类(元组形式)、类内属性
f1 = Foo("MB", 18)
f2 = FFo("CJJ", 18)
print(f1)
print(f2)
自定义元类
#metaclass的本质
class Foo(metaclass=type): # type("Foo", (object,), {})
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
可以定义一个新的元类,利用metaclass参数声明元类
class Mytype(type):
def __init__(self, a, b, c):#需要四个参数
self.a = a
self.b = b
self.c = c
class Foo(metaclass=Mytype): #这里相当于Foo = Foo(self, "Foo", (object,),{}) (这里的self也是Foo,因为赋值给了Foo),相当于执行Mytype的__init__()函数,相当于让Mytype产生一个实例赋值给Foo
def __init__(self, name):
self.name = name
p1 = Foo("alex") #这里的实例化相当于执行的Mytype中默认的__call__()方法
print(p1.name)
print(Foo)
print(p1)
这里使用Foo产生实例相当于调用的元类的__call__()方法,所以想要定制元类还需要重写元类的__call__()方法
class Mytype(type):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def __call__(self, *args, **kwargs):
obj = object.__new__(self)#这一步相当于产生一个对象,这个对象中现在什么都没有,之后将这个对象中封装属性最终赋值给给定的变量
self.__init__(obj, *args, **kwargs)#为了在实例化的时候自定执行类的__init__方法,需要在元类的__call__()方法中写入执行__init__()方法
return obj
class Foo(metaclass=Mytype):
def __init__(self, name):
self.name = name
p1 = Foo("alex")
print(p1.name)
print(Foo)
print(p1)