如何列出Python类及实例中使用基于functools实现的带参装饰器的方法
优化实现方案
核心思路
给自定义装饰器类添加专属的布尔类型标识属性,完全替代脆弱的字符串匹配逻辑,同时统一处理入参为类或实例的场景。
步骤1:修改装饰器添加标识
在你的MyDecorator类中新增专属标记属性,无需改动原有功能逻辑:
from functools import update_wrapper, partial def my_decorator(name): class MyDecorator(object): # 新增专属标识,用于后续检测 _is_my_decorator = True def __init__(self, func): update_wrapper(self, func) self.func = func # 装饰器入参也可以存在这里,后续需要获取时可直接读取 self.decorator_name = name def __get__(self, obj, objtype): """Support instance methods.""" return partial(self.__call__, obj) def __call__(self, obj, *args, **kwargs): return self.func(obj, *args, **kwargs) return MyDecorator class MyClass(object): t=12 @my_decorator("hee") def my_method(self, a): print(a+self.t)
步骤2:重写检测函数
新的检测函数会自动判断入参是类还是实例,直接通过标识属性判断是否为目标装饰器修饰的方法:
def find_my_decorators(obj): # 统一转换为类对象:入参为实例则取其所属类,入参为类则直接使用 cls = obj if isinstance(obj, type) else obj.__class__ matched = [] for attr_name in dir(cls): attr = getattr(cls, attr_name) # 直接通过标识判断,无任何字符串匹配逻辑 if getattr(attr, '_is_my_decorator', False): matched.append(attr_name) return matched
运行效果
和原有实现完全一致,兼容性不受影响:
>>> find_my_decorators(MyClass) ['my_method'] >>> m = MyClass() >>> m.my_method(a=12) 24 >>> find_my_decorators(m) ['my_method']
方案优势
- 逻辑稳定可靠:完全不依赖字符串解析,不会因为类名修改、Python版本调整partial的字符串输出格式导致检测失效
- 无侵入性:原有装饰器的功能、调用方式完全不受影响
- 扩展性强:后续如果需要获取装饰器的入参等信息,直接读取装饰器实例的对应属性即可
内容的提问来源于stack exchange,提问作者Joost Döbken
相关产品推荐
相关产品推荐

