python——元类学习

概念

元类是类的类,就像类是对象的模板一样,元类是类的模板。在 Python 中,一切皆对象,类也是对象。当我们定义一个类时,Python 会在后台使用元类来创建这个类。默认情况下,Python 使用内置的type元类来创建类。

作用

可以自己定制类的某些功能,比如参数类型检查、单例模式等。然后需要使用这些功能的类指定metaclass属性,就会用元类创建类。

类创建的流程

类本质也是对象,是由元类type创建,type创建类时需要传入三个参数

  • 类名 class_name
  • 基类 class_bases
  • 类的名称空间 class_dic
    综上,class关键字帮我们创建一个类应该细分为以下四个过程:

1、拿到类名

2、拿到他的基类们;

3、执行类体代码,拿到类的名称空间;

4、调用元类返回对象(返回的对象就是我们需要的“类”) :type( class_name, class_bases, class_dict )

自定义元类

如果要自定义元类,那么只需要继承type实现类后,再在类中指定metaclass即可,如下:

class MyType(type):
	def __init__(self,class_name,class_bases,class_dic):
		super(Mymeta, self).__init__(class_name, class_bases, class_dic)  # 重用父类的功能
		if not class_name.istitle():
            raise TypeError('类名%s请修改为首字母大写' %class_name)

        if '__doc__' not in class_dic or len(class_dic['__doc__'].strip(' \n')) == 0:
            raise TypeError('类中必须有文档注释,并且文档注释不能为空')

class Demo(object, metaclass=MyType):
	pass

补充

在调用类的时候,会首先自动触发 __ new __方法,执行里面的代码,在触发_init_ 方法

class MyType(type):
    def __init__(self, *args, **kwargs):
        print("第2步:初始化类成员:", args, **kwargs)
        super().__init__(*args, **kwargs)

    def __new__(cls, *args, **kwargs):
        new_cls = super().__new__(cls, *args, **kwargs)
        print("第1步:创建类:", new_cls)
        return new_cls


class Foo(metaclass=MyType):
    v1 = 123

    def func(self):
        pass

在这里插入图片描述
当实例化一个对象时,那么就需要在__call__下返回实例化对象

class MyType(type):
    def __init__(cls, *args, **kwargs):
        print("第2步:初始化类成员:", args, **kwargs)
        super().__init__(*args, **kwargs)

    def __new__(cls, *args, **kwargs):
        new_cls = super().__new__(cls, *args, **kwargs)
        print("第1步:创建类:", new_cls)
        return new_cls

    def __call__(cls, *args, **kwargs):
        print("第3步:创建对象&初始化对象", cls)

        # 1.调用自己那个类的 __new__ 方法去创建对象
        new_object = cls.__new__(cls, *args, **kwargs)

        # 2.调用你自己那个类 __init__放发去初始化
        cls.__init__(new_object, *args, **kwargs)
        return new_object


class Foo(metaclass=MyType):
    v1 = 123

    def func(self):
        pass


obj = Foo()

在这里插入图片描述

应用

drf序列化器

ModelSerializer和Serializer都使用SerializerMetaclass作为元类来控制创建。
在这里插入图片描述
在这里插入图片描述

使用metaclass实现的优势

  • 灵活性‌:通过自定义metaclass,可以灵活地定义类的创建过程,满足不同的序列化需求。

  • 扩展性‌:metaclass提供了扩展基类的能力,使得开发者可以方便地添加新的功能或修改现有行为。

  • 代码复用‌:通过继承和metaclass,可以轻松地复用已有的序列化器类,减少重复代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值