如何用Python装饰器动态生成带_after后缀的函数并更新类Features列表
实现方案
核心思路
- 用无参装饰器给需要生成未来方法的函数做标记,不需要显式传入
Features列表 - 利用Python类的
__init_subclass__钩子,在类初始化阶段自动扫描被标记的方法,生成对应后缀的新方法并挂载到类上,同时更新Features列表 - 新方法的逻辑可以根据业务需求自定义,不需要修改原函数的逻辑
可运行代码
# 无参装饰器,仅做标记用 def gets_future_value(func): func._has_future = True return func class Dog: Features = ['bark'] def __init__(self, name): self.name = name @classmethod def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) # 遍历类的所有成员找被标记的方法 for name, attr in list(cls.__dict__.items()): if callable(attr) and getattr(attr, '_has_future', False): # 可自定义后缀,要生成bark_again就把这里的_after改成_again即可 new_method_name = f'{name}_after' # 自定义新方法的逻辑,这里可以替换为你计算未来特征值的业务代码 def future_method(self, *args, **kwargs): # 示例逻辑:打印对应内容,需要调用原方法的话可以加 attr(self, *args, **kwargs) print(f'Bark after!') # 给新方法设置正确的函数名 future_method.__name__ = new_method_name # 将新方法挂载到类上 setattr(cls, new_method_name, future_method) # 自动更新Features列表 cls.Features.append(new_method_name) @gets_future_value def bark(self): print('Bark!') # 测试 if __name__ == '__main__': d = Dog('Mr. Barkington') print(d.Features) # 输出:['bark', 'bark_after'] d.bark() # 输出:Bark! d.bark_after() # 输出:Bark after!
调整说明
- 如果需要把新方法的后缀改成
_again,只需修改new_method_name = f'{name}_after'里的后缀为_again即可,最终Features列表就会变成['bark', 'bark_again'] future_method内部的逻辑可以完全自定义,比如调用原函数的返回值做加工、计算时序数据的未来值等,都可以在这里实现- 该方案支持继承,后续新增的子类只要给对应方法加
@gets_future_value装饰器,就会自动生成对应未来方法并更新特性列表
内容的提问来源于stack exchange,提问作者SnakeWasTheNameTheyGaveMe
相关产品推荐
相关产品推荐

