【说明】 本文是对元类的基础的理解,不是对元类的底层实现研究。如果觉得内容过浅,请勿多多谅解。
元类(Meta),作为2018年正式公布的计算机科学名词。在计算机编程语言中,其实是一个比较难以理解的名词。之所以那一理解,主要体现如下:
- 对一切皆对象的理解。
- 创建类的类。
- 元类自身是不是也是一个对象。
元类表达的思想
为了说明元类想要表达的思想,我们用生物学上的一些,我们能够理解的层次的概念来进行分类对比(这里不是完整研究生物学分类的,不要来纠结分类的正确性)。
比如生物系统,我们可以简单的划分为:植物、动物、微生物。而对普通大众而言,一般谈论的也就是植物或动物。这也是我们默认意义上理解的生物。因此,我们一般意义上来讲,我们可以在此基础上进行更深层次的分类,比容动物类继续细分为:爬行动物、哺乳动物、飞行动物等等。如此层层展开,到最后具体到一个特定个体的时候。就构成了我们完整的面向对象的体系结构。
比如在Python中,生物等价于object对象,动植物之类的分类则等价于object的子类。如此继承,到最后的个体,则等价于实例化对象的类。
虽然,上述的生物(object类)代表了一切对象化的事物,但是,总是希望,我们在某些特定时机,用一些特殊的方式来表示这个概念,或者在这个概念上增加一些限制性规则,来表示某一个系统的根本,并且与之关联的一切都是基于此概念,但又没有完全脱离这个系统本身。
当然,对于上述想法,我们可以在object的基础上提供一个子类,来作为后续类的基类。但是这样,来看的话,增提还是表现出了继承性。因此,为了避免这样的继承性问题,元类(Meta)的概念就开始发挥他的作用了:那就是存在一个生成类对象的类型,用于作为某种类型的根类表示(这也就是Python的基于type的元类方案了)。
其实大意就是说,虽然微生物也是生物的一种,理论上,我们可以直接继承生物定义一个子类,在让其他微生物种类继承这个类。但是,我们现在不想这么做,因此,我们采取了一种方法,直接定义一个元类,虽然他也有生物本省的一些概念,但是我们并不让他通过继承的特性表现出来,而是我们默认微生物就是一个独立的概念体系。换成Python而言,也就是说:虽然,我后续的类型也都是一个object类型,但是我希望后续的不直接体现出object的概念,而是直接体现出我想要表达的结构体系的概念。这就是元类要表达的思想。
上面用生物体系的方式来描述了一下元类要表达的思想。接着,我们来真正理解元类的概念。
元类理解
在Python,中一切皆对象,而元类则是创建类的类, 一切皆对象,这句话的含义就是无论是我们的实例,还是类其本质都是对象,当然这里所说的类,本身也是包含元类的。这一点可以从type与object之间的关系来得以解释:
在 Python 中,type 和 object 类的对象化是通过元类(metaclass)来实现的。元类是用于创建类的类,它定义了类的创建和初始化过程。
当定义一个类时,Python 会检查类的定义语句中是否指定了元类。如果没有指定元类,默认情况下,使用的是内置元类 type。通过指定不同的元类,可以自定义类的创建和初始化过程。
对于 object 类来说,它的元类就是 type。这意味着 object 类是由 type 类创建的,它继承了 type 类的行为和特性。
接着来看如下示例:
print(f"type 是 object的子类: {issubclass(type, object)}")
print(f"object 是 type的子类: {issubclass(object, type)}")
print(f"type 是 object的实例: {isinstance(type, object)}")
print(f"object 是 type的实例: {isinstance(object, type)}")
得到如下的执行结果
(.venv) ➜ module python ./src/modulea/meta/meta_demo.py
type 是 object的子类: True
object 是 type的子类: False
type 是 object的实例: True
object 是 type的实例: True
从示例我们可以看出,object是type的子类。但是在实例化过程中,确实type和object互为对方的实例化对象。这也证实了,在Python中,object是一切类的根类,而所有的
元类的定义
在 Python 中,元类(metaclass)是用于创建类的类。元类定义了类的创建和初始化过程,控制了如何创建类对象、继承基类、添加属性和方法等。
元类是通过定义一个类来实现的,这个类需要继承自内置的元类 type。通过重写元类的特殊方法,可以自定义类的创建和初始化逻辑。
以下是一个简单的示例,展示了如何定义一个元类:
class BaseMeta(type):
def new(cls, name, bases, attrs):
# 自定义类的创建逻辑
print("创建 class:", name)
return super().new(cls, name, bases, attrs)
def __init__(cls, name, bases, attrs):
# 自定义类的初始化逻辑
print("初始化 class:", name)
super().__init__(name, bases, attrs)
class SubClass(object, metaclass=MyMeta):
def foo(self):
pass
当定义一个新的类时,Python 会执行以下步骤来创建和初始化该类的对象:
解析类定义语句,创建一个类的命名空间。
确定类的元类。如果没有指定元类,则使用默认的元类 type。
使用元类创建类对象。元类会被调用,并传递类名、基类、属性和方法等信息。元类负责创建类对象,并将其初始化。
初始化类对象。类对象的初始化过程包括执行类的定义语句中的代码,创建类的属性和方法等。
在这个过程中,元类起到了关键的作用。它定义了类对象的创建和初始化逻辑,包括如何处理类的属性和方法,如何继承基类等。type 元类是 Python 默认的元类,它提供了创建和初始化类对象的标准逻辑。
总结:
对于元类的概念,就好比绕口令一般,特别是刚开始接触的时候,往往会觉得云山雾绕,这一点只有在伴随着对Python的更深入理解。特别是运用元类的情况下,多思考类与类之间的关系,才能更好的掌握。