Python:type 的另一面
type 本身是类,也是自己的类型。它是一个元类。元类用于实例化并定义类的行为,就像类用于实例化并定义实例的行为一样。
type 是 Python 使用的内置元类。为改变 Python 中类的行为(比如,SomeClass 的行为),我们可以通过继承 type 元类,定义一个自定义元类。元类是在 Python 中进行元编程的一种方法。
定义了某个类后会发生什么情况?
我们首先回顾下已知的内容。Python 程序的基本构建块是:
语句
函数
类
语句用于在程序中执行实际的工作。语句可以在全局范围(模块级别)或局部范围(限于函数内)执行。函数类似代码的基本单元,由用于完成特定任务的一个或多个语句以某种顺序构成。可以在模块级别定义函数,也可以将函数定义为类的方法。类为函数提供面向对象的编程方法。它们定义对象如何进行实例化以及对象的特征(属性和方法)。
类的名称空间被分层为不同的字典。例如:
以下是每次遇到关键字类时发生的情况:
类的主体(语句和函数)被隔离。
创建类的名称空间字典(但尚未填充)。
先执行类的主体,然后使用所有属性、定义的方法以及与类有关的其他一些有用信息来填充名称空间字典。
在基类或要创建的类的元类挂钩(稍后解释)中确定元类。
然后,通过类的名称、基类和属性调用元类,对其进行实例化。
因为 type 是 Python 中的默认元类,所以可以在 Python 中使用 type 来创建类。
type 的另一面
通过一个参数调用 type 时,会生成现有类的 type 信息。通过三个参数调用 type 时,会创建一个新的类对象。调用 type时,参数是类名、基类列表以及指定类的名称空间的字典(所有字段和方法)。
所以:
>>> class SomeClass: pass
等同于:
>>> SomeClass = type('SomeClass', (), {})
以及:
实际等同于:
因此,通过使用自定义元类而不是 type,我们可以将某种行为注入到不太可能的类中。但是在实现元类来改变行为之前,我们来看一下在 Python 中进行元编程更为常见的方法。