调用具有带参数的装饰器的函数

时间:2021-03-01 18:07:13

标签: python decorator

从到目前为止我读过的关于将参数传递给装饰器的教程中,它们都提到了如何装饰函数,例如:

@decorator_with_args(arg)
def foo(*args, **kwargs):
    pass

翻译成:

foo = decorator_with_args(arg)(foo)

def my_decorator(arg):
    def inner_decorator(f):
        def wrapped(*args, **kwargs):
            print('before function')
            response = f(*args, **kwargs)
            print('after function')
            return response
        print('decorating', f, 'with argument', arg)
        return wrapped
    return inner_decorator

@my_decorator('foo')
def my_function(a, b):
    print('in function')
    return a + b

相当于

my_function = my_decorator('foo')(my_function)

这些例子确实是正确的,但不是将我们的函数传递给装饰器并分配给一个更健壮的变量的第二种方法,因为在这里我们可以随心所欲地改变装饰器的参数,例如{ {1}} 或 my_function=my_decorator('foo1')(my_function) 而在第一种情况下,参数似乎总是 'foo' 除非对于不同的调用我们返回并更新 another_function=my_decorator('foo3')(my_function) 参数,或者重新定义函数以便我们的装饰器可以采用不同的参数,例如:

@my_decorator

当从另一个模块导入装饰函数时,这种行为尤其明显,该模块使用默认装饰器参数调用该函数,但不提供修改能力。

如果我遗漏了什么,请纠正我。谢谢。

1 个答案:

答案 0 :(得分:1)

<块引用>

除非对于不同的调用,我们返回并更新 @my_decorator 参数

好吧,你不这样做。那不是装饰师的工作。装饰器改变函数的行为,并且在可重用的情况下这样做。 IE。当您想将相同类型的行为添加到多个函数时,您可以使用装饰器,而无需将用于该行为的代码单独添加到每个函数中。

最后,您将组合一个以特定方式运行的函数。而且您根本不会一直重新定义函数。您定义一个函数一次,然后多次调用它。如果你需要函数每次都有不同的行为,需要你一直重新定义函数,那么,那不是一个理智的函数。

您装饰该函数一次,然后该函数以特定方式运行——作为装饰器+原始函数的组合——并且您可以在定义时向该装饰器传递一些参数以使其以某种方式改变其行为,但是这个定义不应该一直被重新定义,否则你基本上不知道你的函数在任何特定时间点的行为。