元类是"类的类":普通类是元类的实例,正如对象是类的实例。定义 class Foo(metaclass=M) 时,Python 实际调用 M(name, bases, namespace) 来创建 Foo 这个类对象。默认元类是 type。通过在元类中重写 __new__/__init__/__call__,可以在类创建的那一刻检查、修改、注册这个类。
典型使用场景:
- ORM 框架:Django/SQLAlchemy 用元类扫描类体中声明的字段,生成表结构映射——用户只写声明式代码。
- 自动注册:插件系统中让子类定义即自动注册到注册表。
- 接口/契约强制:校验子类必须实现某些方法(现代做法更多用
abc抽象基类或__init_subclass__)。 - 单例:元类里重写
__call__缓存实例。
class Registry(type):
plugins = {}
def __new__(mcs, name, bases, ns):
cls = super().__new__(mcs, name, bases, ns)
if bases: # 跳过基类本身
mcs.plugins[name] = cls
return cls
关键提醒:元类是强大但重型的武器,Tim Peters 的名言"元类是 99% 用户不需要担心的魔法"。简单需求优先考虑类装饰器或 __init_subclass__(3.6+),只有框架级代码才真正需要元类。追问方向:元类与 __init_subclass__ 的取舍、类创建流程(__prepare__ → 类体执行 → 元类调用)。