通过装饰器继承机制向字典中添加方法的实现问题
实现可继承装饰器自动注册方法到类字典的解决方案
你希望实现一个可被继承的装饰器,无需调用被装饰的方法,就能自动将方法添加到类内部的字典中。原代码的问题在于,装饰器的逻辑是在方法被调用时才往实例字典里添加内容,而我们需要在类定义或实例化阶段就完成注册。
方案一:类变量+类方法装饰器(简单直接)
利用类级别的字典存储注册信息,在方法被装饰时(类定义阶段)就完成注册,实例化时将类字典同步到实例:
class A: # 类变量存储注册的方法,子类可独立扩展 class_mydict = {} def __init__(self): # 实例化时复制类字典到实例,保证每个实例有独立的字典副本 self.mydict = self.class_mydict.copy() @classmethod def Appenddict(cls, key): def _Appenddict(function): # 类定义阶段直接注册到类的字典 cls.class_mydict[key] = function # 返回原方法,无需包装器(因为不需要在调用时执行逻辑) return function return _Appenddict class B(A): # 子类单独定义类字典,避免与父类的注册内容混淆 class_mydict = {} def __init__(self): super().__init__() # 使用子类的Appenddict装饰器(或父类的A.Appenddict,根据需求选择) @B.Appenddict("Key1") def MyMethod(self): print("My Method") B1 = B() print(B1.mydict) # 实例化后直接输出: {'Key1': <function B.MyMethod at ...>} B1.MyMethod() print(B1.mydict) # 内容保持不变,注册已在类定义时完成
核心逻辑:
- 将
Appenddict改为类方法,使其能访问当前类的class_mydict - 装饰器在方法被定义时(类加载阶段)就完成注册,无需等待方法调用
- 实例化时复制类字典到实例,保证每个实例的字典独立(如果不需要独立,直接引用类字典即可)
方案二:元类实现(灵活扩展)
如果需要更复杂的注册逻辑,或者不想依赖类变量,可以用元类在类创建时收集被装饰的方法,实例化时自动同步到实例字典:
class RegistryMeta(type): def __new__(cls, name, bases, attrs): # 扫描类的所有属性,收集带有注册标记的方法 registered_methods = {} for attr_name, attr_value in attrs.items(): if hasattr(attr_value, '_register_key'): registered_methods[attr_value._register_key] = attr_value # 将收集到的方法存入类的属性 attrs['_registered_methods'] = registered_methods return super().__new__(cls, name, bases, attrs) class A(metaclass=RegistryMeta): def __init__(self): self.mydict = {} # 实例化时自动将类中注册的方法同步到实例字典 self.mydict.update(self._registered_methods) @staticmethod def Appenddict(key): def _Appenddict(function): # 给被装饰的方法添加注册标记,供元类识别 function._register_key = key return function return _Appenddict class B(A): def __init__(self): super().__init__() @A.Appenddict("Key1") def MyMethod(self): print("My Method") B1 = B() print(B1.mydict) # 实例化后直接输出: {'Key1': <function B.MyMethod at ...>} B1.MyMethod() print(B1.mydict) # 内容保持不变
核心逻辑:
- 元类
RegistryMeta在类被创建时,自动扫描并收集所有带有_register_key标记的方法 - 父类
A的__init__方法在实例化时,将类中收集到的方法同步到实例字典 - 装饰器仅负责给方法添加标记,逻辑更解耦,适合后续扩展复杂的注册规则
内容的提问来源于stack exchange,提问作者MJ12
相关产品推荐
相关产品推荐

