You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过装饰器继承机制向字典中添加方法的实现问题

实现可继承装饰器自动注册方法到类字典的解决方案

你希望实现一个可被继承的装饰器,无需调用被装饰的方法,就能自动将方法添加到类内部的字典中。原代码的问题在于,装饰器的逻辑是在方法被调用时才往实例字典里添加内容,而我们需要在类定义或实例化阶段就完成注册。

方案一:类变量+类方法装饰器(简单直接)

利用类级别的字典存储注册信息,在方法被装饰时(类定义阶段)就完成注册,实例化时将类字典同步到实例:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:53:21