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

如何实现支持@Decorator(t=3)用法的类装饰器并正确为self.f赋值

问题根源

你写的类装饰器没有处理带参数调用的场景。当使用@Decorator(t=3)这种带参数的写法时,Python会先实例化一次Decorator类(这时候f参数为None),再把被装饰的函数作为参数传入该实例的__call__方法,原来的__call__逻辑没有处理这一步,所以self.f一直是空的。

解决方案

调整__call__方法的逻辑,判断如果self.f为空,就把传入的第一个参数作为被装饰函数存到self.f并返回当前实例即可,同时补充函数返回值逻辑和参考的函数装饰器对齐,修改后的完整代码如下:

#!/usr/bin/env python3

class Decorator:
    def __init__(self, f=None, *, t=2):
        self.t = t
        self.f = f

    def __call__(self, *args, **kwargs):
        # 处理带参数装饰场景:第一次调用接收被装饰函数
        if self.f is None:
            self.f = args[0]
            return self
        # 正常调用函数的逻辑
        print(f'{self.f = !r}')
        value = None
        for _ in range(self.t):
            value = self.f(*args, **kwargs)
        return value

@Decorator
def hello4(name):
    print(f'Hello {name}')

if __name__ == '__main__':
    hello4("gert")

@Decorator(t=3)
def hello6(name):
    print(f'Hello {name}')

if __name__ == '__main__':
    hello6("gert")

运行效果

输出和你提供的函数装饰器完全一致:

self.f = <function hello4 at 0x...>
Hello gert
Hello gert
self.f = <function hello6 at 0x...>
Hello gert
Hello gert
Hello gert

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 00:57:04