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

如何使用同一个装饰器同时修饰函数和类方法?

如何使用同一个装饰器同时修饰函数和类方法?

哎,这个问题我之前也踩过坑!完全不用写两个名字不一样的装饰器,咱们只要把装饰器改得更灵活一点,就能让它同时适配普通函数和类方法啦~

先说说你原来的代码为啥会出问题:普通函数sumup接收两个参数a和b,但类里的sumup方法第一个参数是self(也就是类实例本身),原来的装饰器里的decorator函数固定只接收a和b两个参数。当你调用cls.sumup(4,8)时,Python实际会把cls(实例)、4、8这三个参数传进去,可装饰器的decorator只接两个参数,自然就会报参数不匹配的错误。

那怎么改呢?其实很简单,让装饰器的内层函数支持可变参数就行,用*args来接收所有位置参数,不管是函数的两个参数,还是方法的三个参数,都能一股脑传进去给原函数。

修改后的装饰器代码是这样的:

from functools import wraps

def nice(f):
    @wraps(f)
    def decorator(*args, **kwargs):
        # 把所有接收到的参数原封不动传给原函数
        result = f(*args, **kwargs)
        return 'result is: %s' % str(result)
    
    return decorator

然后你原来的测试代码完全不用改,直接用这个装饰器同时修饰函数和类方法:

@nice
def sumup(a, b):
    return a + b

class Test:
    def __init__(self):
        pass
    
    @nice
    def sumup(self, a, b):
        return a + b

print(sumup(2, 6))  # 输出:result is: 8
cls = Test()
print(cls.sumup(4, 8))  # 输出:result is: 12

你看,这样不管是普通函数还是类方法,这个装饰器都能完美胜任!

如果你的原函数还需要接收关键字参数,那上面代码里的**kwargs已经帮你处理好了,连关键字参数也能正确传递,通用性更强。

当然,如果你想更严谨地处理,也可以通过检查原函数的参数签名来区分是函数还是方法,但用*args+**kwargs是最简洁通用的方案,比写两个不同名字的装饰器优雅太多了~

备注:内容来源于stack exchange,提问作者IzaeDA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:33:09