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

为何仅调用一个被装饰函数时,两个自定义装饰器均被触发?

问题排查与修复:Python装饰器提前打印信息的问题

问题原因

你当前的装饰器逻辑错误地把打印操作放在了__call__方法的顶层,而非包装函数(wrapper)内部。Python中使用@装饰器语法时,执行流程是:

  1. 先实例化装饰器对象(比如Important(reason="..."))
  2. 立即调用该对象的__call__方法,传入被装饰的函数(比如critical_task)
  3. 这一步发生在类定义加载阶段,和后续是否调用被装饰函数无关

因此不管你是否调用目标函数,__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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:24:58