关于元类的一些说明

1. 什么是元类?

在我们不自定义元类的前提下,元类指的就是 type,而type实际上就是一个类。

2. 元类的作用?

元类是用于创建某个类的类,即说明了我要创建的类是通过哪个类创建的。

3. 对创建类的重新认识

大多是情况下创建类的方式:

classFoo(object):pass

然而也可以这样创建

Foo = type("Foo",(object,),{})

这两种创建类的效果等同。既然type是一个类,那么str和int是不是也是一个类?答案是肯定的。

python Meta类 元数据 python元类的作用_构造方法

str和int既然都是一个类,那么这两个类是由哪个类创建的?

python Meta类 元数据 python元类的作用_自定义_02

由此可以看出,我们使用class创建一个类,使用str和int创建一个对象,其本质都是由 type这个类创建。既然我们知道了类都是由type这个类创建,那么是怎么通过类来创建类。对于Python而言,一切皆对象,即类也是一个对象。如果class只是用来创建一个类(即我们并不知道执行class实际上执行的是type),那么对于使用class关键子创建类的可以进行以下的分解操作:

步骤一:

Foo = type("Foo",(object,),{}) ,使用type这个类创建一个类名为Foo,继承object类的类,既然创建类的实例就会执行type类中的构造方法,而此时等号左边的Foo接收的是type类构造出来的实例对象。

步骤二:

classFoo():pass ,将上述步骤生成的Foo变量进行传入,此时的Foo对于class来说是一个类,而该类其实就是type类的实例对象。

既然我们知道了类其实都是由元类type进行创建的,那么我们就可以自定义一个元类类创建其他的类。

自定义元类

class MyType(type): #自定义的元类需要继承元类type

def __init__(self,*args,**kwargs):print(‘init‘)

super(MyType,self).__init__(*args,**kwargs)def __call__(self, *args, **kwargs):print(‘call本质:调用类的__new__,再调用类的__init__‘)return super(MyType,self).__call__( *args, **kwargs)class Base(metaclass=MyType): #使用自定义的元类创建Base类

pass

输出结果: init 。指定了metaclass属性,则会根据自定义元类的构造方法进行Base类的创建,因此打印出字符串“init”。也就是说,我们通过Mytype这个元类创建了Base类,更准确的说应该是Base类的实例对象。