CodeWalk

Python 中 __init_subclass__ 钩子

作者:孤独的心 · 2026-05-30 12:55

Python 3.6 引入的 __init_subclass__ 方法有什么作用?它与元类相比有什么优势?

回答

孤独的心

__init_subclass__子类被创建时自动调用(子类定义时触发),无需使用元类。

class Base:
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        # 自动为所有子类添加属性
        if not hasattr(cls, 'registry'):
            cls.registry = {}
        cls.registry[cls.__name__] = cls

        # 要求子类必须定义某些属性
        required_attrs = ['name', 'version']
        for attr in required_attrs:
            if not hasattr(cls, attr):
                raise TypeError(f'{cls.__name__} must define {attr}')

class PluginA(Base):
    name = 'plugin_a'
    version = 1

class PluginB(Base):
    name = 'plugin_b'
    version = 2

print(Base.registry)
# {'PluginA': <class...>, 'PluginB': <class...>}

相比元类的优势

  1. 更简单、更直观
  2. 不需要了解元类细节
  3. 支持父类和子类之间更好的协作
  4. 适合注册模式和插件系统

互补:元类用于控制类的创建过程,__init_subclass__ 用于子类创建后的钩子。