zoukankan      html  css  js  c++  java
  • python 通过元类控制类的创建

    一、python中如何创建类?

    1. 直接定义类

    class A:
       a = 'a'

    2. 通过type对象创建

    在python中一切都是对象

    在上面这张图中,A是我们平常在python中写的类,它可以创建一个对象a。其实A这个类也是一个对象,它是type类的对象,可以说type类是用来创建类对象的类,我们平常写的类都是type类创建的对象,再由创建的对象再去创建我们平常使用的对象,我们可以看看type的官方文档

    type(object_or_name, bases, dict)
    type(object) -> the object's type
    type(name, bases, dict) -> a new type

    type有另一种用法type(name, bases, dict)来创建类 中,name是这个类的名字,bases是这个类的基类(是一个元组),dict是这个类的属性(是一个字典),我们通过type实现上面的例子中A类的创建

    A = type('A', (), {'a': 'a'})

    二、什么是元类编程?

    我们已经知道,类也是对象,那么我们在创建类的时候,可不可以控制类的创建过程?当然是可以的,这就是元类编程。

    三、如何实现元类编程?

    1. 在要定义的类中使用__new__方法

    class A:
        def __new__(cls, *args, **kwargs):
            cls.a = 'a'
            return super().__new__(cls, *args, **kwargs)

    这样就实现了创建A类的时候,添加了一个类属性a(注意的是,__new__方法要返回一个创建的对象,当然,我们也可以返回其他东西;另一个注意点是__new__方法要在实例化的时候才会运行,所以,类属性a必须是在A实例化后才会出现)

    2. 使用metaclass关键字,使用metaclass关键字的时候,我们要定义一个type类

    class B(type):
        def __init__(self, *args, **kwargs):
            self.a = 'a'
            super().__init__(*args, **kwargs)
    
    
    class A(metaclass=B):
        pass

    我们定义了一个B类继承type,在A类创建的时候传递关键字metaclass=B,就会执行B类种的代码,控制A类的创建,这个例子也是为A类添加了一个类属性a。我们还可以在B类中使用__init__,__call__方法。

    四、python中元类编程执行的顺序

    class MetaClass(type):
        # 定义A类的时候就会调用
        def __init__(self, *args, **kwargs):
            print('MetaClass __init__')
            super().__init__(*args, **kwargs)
    
        # 定义A类的时候,就会调用
        def __new__(cls, *args, **kwargs):
            print('MetaClass __new__')
            # *args 里面包含了创建A类的参数
            return super().__new__(cls, *args, **kwargs)
    
        # A实例化的时候才会去调用call
        def __call__(self, *args, **kwargs):
            print('MetaClass __call__')
            # 这儿其实是去调用A类需要实例化的所有方法
            return super().__call__(*args, **kwargs)
    
    
    class A(metaclass=MetaClass):
        def __init__(self):
            print('A __init__')
    
        def __new__(cls, *args, **kwargs):
            print('A __new__')
            return super().__new__(cls, *args, **kwargs)
    
    
    a = A()
    
    
    # 输出
    MetaClass __new__
    MetaClass __init__
    MetaClass __call__
    A __new__
    A __init__

    五、总结

    使用元类编程可以让我们在创建类的时候,给类添加一些额外的信息。但元类编程是python中难以理解的地方之一,而且工作中,大部分时候都是不会用到的,我们普通的类定义方式就可以解决问题了,若果说有99%的时候你需要控制创建类的过程,那就使用元类编程吧。

    理解元类,大家可以参考这篇文章  what are metaclass in python?

  • 相关阅读:
    python制作一个塔防射箭游戏
    有两个链表a和b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同 学号的那些结点。
    python实现一个简单的21点游戏
    C语音,函数padd的功能是调整pa指向的链表中结点的位置,使得所有x值为偶数的结点出现在链表的前半部,所有x值为奇数的结点出现在链表的后半部。
    scratch绘制特殊图形1
    验证哥德巴赫猜想,输出6-100之间的偶数等于两个质数之和
    写一函数check检测字符串中的左右括号数是否匹配
    C语言文件操作题,将整数1-10及其算术平方根存入文件,再读取出来显示在屏幕上
    湖南2020对口计算机32题第1、2、3小题
    基础
  • 原文地址:https://www.cnblogs.com/time-read/p/10603950.html
Copyright © 2011-2022 走看看