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

Python类内用functools wraps装饰器报错:缺少func参数

解决类内实例方法作为装饰器的TypeError问题

你遇到的TypeError: adder() missing 1 required positional argument: 'func',本质是类内的实例方法不能直接用作装饰器。

因为装饰器在类定义阶段就会被执行(也就是当你写@adder修饰oper时,Python会立刻调用adder(oper)),但此时Inherit类还没有创建任何实例,实例方法adder需要的第一个参数self无法自动传入——本来实例方法的调用逻辑是实例.adder(func),但类定义阶段没有实例,直接调用adder(oper)就会少传一个self参数,Python便误以为缺少的是func。

方案一:将装饰器改为静态方法

静态方法不需要绑定实例或类,没有self参数,适合这种不需要访问类/实例属性的装饰器。修改后代码如下:

from functools import wraps


class Parent():
    def __init__(self, a):
        self.a = a

    def oper(self, b):
        return self.a + b


class Inherit(Parent):
    @staticmethod
    def adder(func):
        @wraps(func)
        def wrapping(*args, **kwargs):
            # 实例方法的第一个参数是self,不能对其平方,仅处理后续业务参数
            new_args = [args[0]] + [i**2 for i in args[1:]]
            return func(*new_args, **kwargs)
        return wrapping

    @adder
    def oper(self, b):
        return super().oper(b)


a = Parent(10)
print(a.oper(10))  # 输出20
b = Inherit(10)
print(b.oper(10))  # 输出10 + 10² = 110

方案二:将装饰器移到类外部

如果装饰器不需要和类绑定,直接定义在类外更简洁:

from functools import wraps

def adder(func):
    @wraps(func)
    def wrapping(*args, **kwargs):
        new_args = [args[0]] + [i**2 for i in args[1:]]
        return func(*new_args, **kwargs)
    return wrapping

class Parent():
    def __init__(self, a):
        self.a = a

    def oper(self, b):
        return self.a + b


class Inherit(Parent):
    @adder
    def oper(self, b):
        return super().oper(b)


a = Parent(10)
print(a.oper(10))  # 20
b = Inherit(10)
print(b.oper(10))  # 110

另外需要注意:你原代码的装饰器逻辑有个隐藏问题——把所有args都平方,包括实例方法的第一个参数self,这会导致调用父类方法时传入错误的self对象。上面的代码已经修正了这个问题,只对self之后的业务参数进行平方操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:25:15