Python 中 __init_subclass__ 钩子
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...>}
相比元类的优势:
- 更简单、更直观
- 不需要了解元类细节
- 支持父类和子类之间更好的协作
- 适合注册模式和插件系统
互补:元类用于控制类的创建过程,__init_subclass__ 用于子类创建后的钩子。