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

Python基于类实现带参数日志装饰器的TypeError错误解决

报错根因

带参数的类装饰器执行流程和无参数的实现完全不同:

  • 无参数用法@logger:直接把被装饰函数作为参数传入类的__init__方法完成实例化,之后调用实例的__call__方法得到替换后的函数
  • 带参数用法@logger(response="debug"):先把括号内的配置参数传入__init__生成装饰器实例,再把被装饰函数作为参数传入该实例的__call__方法,最终得到替换后的函数

你原有代码把func设为__init__的必填参数,但使用装饰器时加了括号传了response参数,此时__init__只会收到response参数,没有func入参,自然抛出缺少参数的错误。

方案说明

你给出的最终解决方案完全符合带参数类装饰器的设计逻辑:

  1. __init__仅接收装饰器配置参数response,完成初始化
  2. __call__接收被装饰函数func,完成函数绑定、原函数元信息拷贝,最后根据配置的response返回对应日志级别的处理方法
  3. debug/info方法分别实现不同级别的日志打印、执行计时、原函数调用逻辑

另外可以补充一个优化注意点:如果需要用同一个装饰器实例装饰多个函数,建议把日志处理逻辑改成闭包实现,避免多函数装饰时self.func属性被覆盖的问题,单函数使用场景下现有代码可直接正常运行。

class logger:

    def __init__(self, response:str = "debug"):
        self.logger = getLogger()
        self.response = response

    def __call__(self, func:callable):
        update_wrapper(self, func)
        self.func = func
        return getattr(self, self.response)

    def debug(self, *args, **kwargs):
        self.logger.debug(f"Running {self.func.__name__} (type:{type(self.func)}) with id: {id(self)} at {datetime.now()}")
        start = perf_counter()
        value = self.func(*args, **kwargs)
        end = perf_counter()
        self.logger.debug(f"""Completed {self.func.__name__} with id: {id(self)} at {datetime.now()}.
            Total Time to run: {end - start:.6f}s""")
        return value

    def info(self, *args, **kwargs):
        self.logger.info(f"Running {self.func.__name__} at {datetime.now()}.")
        return self.func(*args, **kwargs)

内容的提问来源于stack exchange,提问作者WolVes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:45:04