Python条件装饰器实现问题:指定装饰器时返回函数引用排查
问题分析与修复:条件装饰器返回函数引用而非预期结果
嘿,咱们来拆解下你的代码问题出在哪。当你传入decorator='int'时,控制台输出函数引用而非预期的1,核心问题出在conditional_decorator类的__call__方法里的这一行:
return decorator(self.func(*args, **kwargs))
错误原因拆解
你这里的逻辑完全搞反了:
self.func(*args, **kwargs)会直接执行原函数,返回结果1- 然后你把这个整数结果传给了
int_decorator,但int_decorator的设计是接收一个函数作为参数,返回包装后的函数对象 - 所以最终返回的是
wrapper函数的引用,而不是执行装饰后函数得到的结果
修复方案
正确的逻辑应该是:先给原函数应用对应的装饰器,得到装饰后的函数,再调用这个装饰后的函数并传入参数。同时,我们可以把decorator参数从kwargs中移除,避免它被传递给原函数(如果原函数不需要这个参数的话)。
修正后的完整代码如下:
def int_decorator(func): # checks whether the args passed is of type int. def wrapper(*args, **kwargs): a, b = args if not (isinstance(a, int) and isinstance(b, int)): return return func(*args, **kwargs) return wrapper decorator_mapping = { 'int': int_decorator } class conditional_decorator(object): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): # 先取出decorator参数,避免传递给原函数 decorator_name = kwargs.pop('decorator', None) decorator = decorator_mapping.get(decorator_name) if not decorator: # 没有匹配的装饰器,直接调用原函数 return self.func(*args, **kwargs) # 先装饰原函数,再调用装饰后的函数 decorated_func = decorator(self.func) return decorated_func(*args, **kwargs) @conditional_decorator def func(a, b, *args, **kwargs): return 1 # 测试用例 print(func(1, 2, decorator='int')) # 输出1,符合预期 print(func('a', 'b', decorator='int')) # 输出None,因为参数类型不匹配 print(func(1, 2)) # 输出1,未指定装饰器时正常运行
关键修改点说明
- 用
kwargs.pop('decorator', None)取出装饰器名称,同时从kwargs中移除该参数,保证原函数只接收它需要的参数 - 替换了错误的调用逻辑:先通过
decorator(self.func)得到装饰后的函数,再调用这个函数并传入参数*args, **kwargs
这样修改后,无论是指定匹配的装饰器还是不指定,都能得到预期的结果啦。
内容的提问来源于stack exchange,提问作者Praful Bagai
相关产品推荐
相关产品推荐

