考虑以下Python代码的输出结果: class Meta(type): def __new__(cls, name, bases, dct): dct['version'] = 1.0 return super().__new__(cls, name, bases, dct) class Base(metaclass=Meta): pass class Child(Base): pass print(Child.version)
1. 元类(metaclass)是什么?
type。class MyClass: ...,Python 实际上会调用 type('MyClass', (), {...}) 来创建这个类。metaclass=Meta,那么 Python 就会用 Meta 而不是 type 来创建这个类。Meta.__new__ 做了什么?
def __new__(cls, name, bases, dct): dct['version'] = 1.0 return super().__new__(cls, name, bases, dct)
name: 要创建的类名(比如 'Base')bases: 父类元组(比如 (object,) 或 (Base,))dct: 类的属性字典(就是你在 class 里定义的方法、变量等)👉 这里它往 dct 里加了一个属性:version = 1.0
也就是说:所有用 Meta 作为元类的类,都会自动拥有 version = 1.0
Base 使用了元类 Meta
1class Base(metaclass=Meta): 2 passBase 这个类时,会调用 Meta.__new__Base.version == 1.0Child 继承自 Base
1class Child(Base): 2 passChild 没有显式指定 metaclassChild 的创建也会使用 MetaChild 的创建也会触发 Meta.__new__
Base 的元类是 MetaChild 继承 BaseBase 的元类(即 Meta)来创建 ChildMeta.__new__ 会被调用 两次:
BaseChild因此,在创建 Child 时,Meta.__new__ 又执行了一次,又往 Child 的 dct 里加了 version = 1.0
所以 Child.version 不仅能通过继承得到,它自己也有这个属性!