类是 type 类的实例
Python 3 中,用户定义的类是 type 的 1 个实例,type 是 1 个类。
>>> class C: pass
>>> isinstance(C, type)
True
>>> type(type)
<class 'type'>
元类是 type 类的子类
Python 2 中的新式类和 Python 3 中:
元类是 type 类的 1 个子类。
__new__
和 __init__
__new__
:用于创建、返回新的 类;
__init__
:用于初始化新创建的 类。
class 语句协议
class 语句协议:在 class 语句的末尾,调用 type 对象来创建 类。
class = type(classname, superclasses, attributedict)
type 对象反过来定义了 1 个 __call__
方法,当调用 type 的时候,自动调用 2 个方法:
type.__new__(typeclass, classname, superclasses, attributedict)
type.__init__(class, classname, superclasses, attributedict)
在类定义中使用元类
Python 3 中:
class Spam(Eggs, metaclass=Meta): pass
当以这样的方式使用元类的时候,在 class 语句的底部,修改为调用 元类,而不是 type :
class = Meta(classname, superclasses, attributedict)
由于 元类 Meta 是 type 的 1 个子类,所以 type 类的 __call__
方法把创建、初始化新的类对象的调用委托给元类
Meta.__new__(Meta, classname, superclasses, attributedict)
Meta.__init__(class, classname, superclasses, attributedict)
编写元类
基本元类
class Meta(type):
def __new__(meta, classname, supers, classdict):
return type.__new__(meta, classname, supers, classdict)
>>> class MetaOne(type):
def __new__(meta, classname, supers, classdict):
print("In MetaOne.new:", classname, supers, classdict, sep='\n...')
return type.__new__(meta, classname, supers, classdict)
def __init__(meta, classname, supers, classdict):
print("In MetaOne.init:", classname, supers, classdict, sep='\n...')
print('...init class object', list(classdict.keys()))
>>> class Spam(Eggs, metaclass=MetaOne):
data=1
def meth(self, arg):
pass
输出:
In MetaOne.new:
...Spam
...(<class '__main__.Eggs'>,)
...{'__qualname__': 'Spam', 'data': 1, '__module__': '__main__', 'meth': <function Spam.meth at 0x0000029C5ED74048>}
In MetaOne.init:
...Spam
...(<class '__main__.Eggs'>,)
...{'__qualname__': 'Spam', 'data': 1, '__module__': '__main__', 'meth': <function Spam.meth at 0x0000029C5ED74048>}
...init class object ['__qualname__', 'data', '__module__', 'meth']
参考文献:
- Python 学习手册 - 第 39 章。