如何实现对Cython扩展类型子类的追踪?
追踪Cython扩展类型的子类(替代元类方案)
由于Cython扩展类型不支持自定义元类,以下是几种可行的替代方案,用于在子类继承时执行特定逻辑:
方法1:使用__init_subclass__(Python 3.6+推荐)
Python 3.6引入的__init_subclass__类方法可以被Cython扩展类型实现,子类继承时会自动触发该方法,无需依赖元类。
示例Cython代码(.pyx文件):
cdef class BaseExtensionType: @classmethod def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) # 自定义追踪逻辑:记录子类到类属性 if not hasattr(BaseExtensionType, '_tracked_subclasses'): BaseExtensionType._tracked_subclasses = [] BaseExtensionType._tracked_subclasses.append(cls) print(f"已追踪新子类: {cls.__name__}")
Python端继承示例:
from your_cython_module import BaseExtensionType class SubTypeA(BaseExtensionType): pass class SubTypeB(BaseExtensionType): pass # 查看已追踪的子类 print(BaseExtensionType._tracked_subclasses)
方法2:手动注册机制(兼容Python 2/3)
如果需要兼容旧版本Python,可以实现显式注册装饰器,让子类主动完成注册:
Cython代码:
cdef class BaseExtensionType: _registered_subclasses = [] @classmethod def register_subclass(cls, subclass): if subclass not in cls._registered_subclasses: cls._registered_subclasses.append(subclass) # 执行自定义逻辑 print(f"已注册子类: {subclass.__name__}")
Python端使用:
from your_cython_module import BaseExtensionType @BaseExtensionType.register_subclass class SubTypeA(BaseExtensionType): pass class SubTypeB(BaseExtensionType): pass # 手动注册未通过装饰器注册的子类 BaseExtensionType.register_subclass(SubTypeB)
方法3:实例化时触发追踪(进阶)
如果允许在子类首次实例化时再执行逻辑,可以在Cython的__cinit__方法中检查类型:
cdef class BaseExtensionType: _subclasses = set() def __cinit__(self): cls = type(self) if cls is not BaseExtensionType and cls not in BaseExtensionType._subclasses: BaseExtensionType._subclasses.add(cls) print(f"首次实例化时发现新子类: {cls.__name__}")
注意:此方法仅在子类被实例化时触发,定义子类但不实例化不会执行追踪逻辑。
内容的提问来源于stack exchange,提问作者Rafael Benevides
相关产品推荐
相关产品推荐

