首页 > 解决方案 > 调用具有带参数的装饰器的函数

问题描述

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

@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)

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

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

@my_decorator('foo5')
def another_function(a, b):
    print('in function')
    return a + b

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

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

标签: pythondecorator

解决方案


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

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

最后,您正在编写一个以某种方式运行的函数。而且您根本不会一直到处重新定义功能。您定义一个函数一次,然后多次调用它。如果您需要该函数每次都表现不同,则需要您一直重新定义该函数,那么这不是一个正常的函数。

您对函数进行一次装饰,然后该函数以特定方式运行 - 作为装饰器 + 原始函数的组合 - 您可以在定义时将一些参数传递给该装饰器以使其以某种方式改变其行为,但是这定义不应该一直重新定义,或者您基本上不知道您的函数在任何特定时间点的行为方式。


推荐阅读