装饰函数的参数如何工作?

How do the arguments of a decorated function work?

var = float(input('Enter a number: '))


def math_test(func):
    def wrapper(*args, **kwargs):
        func(var)
    return wrapper


@math_test
def times10(x):
    print(x * 10)


times10()

为什么调用函数times10()时不需要把参数var放在括号里?

当我调用 func() 时没有键入参数 var 时,我收到一条错误消息说需要位置参数 x...所以当我输入 vartimes10() 我得到了同样的错误。

然而,当我将参数放在 func() 中时,它工作正常。

包装函数不应该知道 times10() 中的参数 var 也应该是 func() 中的参数吗?

编辑:


var = float(input('Enter a number: '))


def math_test(func):
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
    return wrapper


@math_test
def times10(x):
    print(x * 10)

times10(var)

这个修饰函数:

@math_test
def times10(x):
    print(x * 10)

将翻译成:

times10 = math_test(times10)

这意味着 times10 现在等同于:

def wrapper(*args, **kwargs):
    func(var)

其中可调用 func 指向 times10 的原始实现。为了进一步形象化,可以这样想:

def times10(*args, **kwargs):
    def original_times10(x):
        print(x * 10)
    original_times10(var)
  • 如果你调用 func(var),它是 original_times10(var) 的同义词,那么它将起作用,因为 original_times10 被传递 var,这将被放入参数 x.
  • 如果你调用 func(),它与 original_times10() 同义,它显然不起作用,因为 original_times10 需要输入 x 但你没有通过什么都行。

请注意,您要做的是严格将固定参数 var 传递给 times10 的原始实现:

func(var)

根据您的用例,我相信您应该做的是传递实际参数:

func(*args, **kwargs)

这样,无论您传递给 times10 的装饰函数,都会传递给 times10 的原始实现。