为何仅调用一个被装饰函数时,两个自定义装饰器均被触发?
问题排查与修复:Python装饰器提前打印信息的问题
问题原因
你当前的装饰器逻辑错误地把打印操作放在了__call__方法的顶层,而非包装函数(wrapper)内部。Python中使用@装饰器语法时,执行流程是:
- 先实例化装饰器对象(比如
Important(reason="...")) - 立即调用该对象的
__call__方法,传入被装饰的函数(比如critical_task) - 这一步发生在类定义加载阶段,和后续是否调用被装饰函数无关
因此不管你是否调用目标函数,__call__里的打印语句都会在类加载时执行,这就是为什么只调用critical_task却输出了两个装饰器信息的原因。
修复方案
把打印逻辑移到wrapper函数内部,这样只有当被装饰的函数被调用时,才会触发打印:
修改BaseDecorator类的__call__方法:
class BaseDecorator(object): """ Base decorator class """ def __init__(self, message, source=''): self.message = message self.source = source def __call__(self, func): def wrapper(*args, **kwargs): # 打印逻辑移至wrapper内部,仅在函数调用时执行 print(f"{type(func).__name__.capitalize()} `{func.__name__}` {self.message}") if self.source: print(f"Source: {self.source}") return func(*args, **kwargs) return wrapper
验证效果
修改后运行原测试代码:
from decorators_module import Important, Copied class Solution: @Important(reason="This function does something crucial.") def critical_task(self): ... @Copied(source="Inspired by StackOverflow") def helper_function(self): ... if __name__ == '__main__': solution = Solution() solution.critical_task() # Only this function is called
此时只会输出Important装饰器的信息:
Function `critical_task` is important: This function does something crucial.
只有当后续调用helper_function()时,才会打印Copied的相关信息。
内容的提问来源于stack exchange,提问作者Norman Yi
相关产品推荐
相关产品推荐

