【问题标题】:Calling a function which has a decorator with arguments调用具有带参数的装饰器的函数
【发布时间】:2021-03-01 18:07:13
【问题描述】:

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

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

这些例子确实是正确的,但不是将我们的函数传递给装饰器并分配给更健壮的变量的第二种方法,因为在这里我们可以随意更改装饰器的参数,例如@ 987654325@ 或 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

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

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

【问题讨论】:

  • 通常不需要将动态参数传递给装饰器......!?装饰器在函数声明时应用,而不是在调用时应用。如果您需要在调用时将动态参数传递给装饰器,那么这不是装饰器的工作。
  • 谢谢@deceze,这就解释了。

标签: python decorator


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2014-07-21
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2014-02-21
    相关资源
    最近更新 更多