【问题标题】:How to use a "double layered" decorator without using the @ syntax?如何在不使用 @ 语法的情况下使用“双层”装饰器?
【发布时间】:2019-03-25 07:35:54
【问题描述】:

假设我有这个装饰器:

def decorator_with_args(decorator_arg1, decorator_arg2):                
    def decorator(func):
        def wrapped(*args, **kwargs):
            if decorator_arg1 == 'arg1' and decorator_arg2 == 'arg2':
                return func(*args, **kwargs)
        return wrapped
    return decorator

通常你会像这样装饰一个函数:

@decorator_with_args('arg1', 'arg2')
def function():
    return 'foo'

>>> foo = function()
'foo'

如何在不使用@ 语法的情况下调用它?

我知道,如果它只是一个单层装饰器(即没有 args 的装饰器),那么你调用它的方式就是将它包装在装饰器函数中,如下所示:

>>> foo = decorator(function)
'foo'

注意function 没有被调用。如果装饰器和函数都有需要传递的参数,这将如何工作?

>>> foo = decorator_with_args(decorator(wrapped_function))

但是那么装饰器的*args**kwargs和原来的函数去哪里了呢?

【问题讨论】:

  • 这毫无意义。 decoratordecorator_with_args 之外不存在。
  • foo = decorator_with_args('arg1', 'arg2)(function)()
  • @Aran-Fey 抱歉,我的意思是假设性的。

标签: python python-3.x decorator wrapper


【解决方案1】:

decorator_with_args() 是一个装饰器工厂——即一个返回装饰器的函数。这意味着要在没有 @ 语法的情况下使用它,您需要使用它的参数调用它,然后使用您的函数作为参数调用结果。

看起来是这样的:

def function():
    return 'foo'

function = decorator_with_args('arg1', 'arg2')(function)

>>> function()
'foo'

请注意,这类似于使用带有或不带有 @ 语法的常规装饰器之间的区别:

@deco
def func(arg):
    # ...

def func(arg):
    # ...

func = deco(func)

作为

@deco_fac(x, y)
def func(arg):
    # ...

def func(arg):
    # ...

func = deco_fac(x, y)(func)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 2012-02-08
    • 2018-04-17
    • 1970-01-01
    • 2016-07-05
    相关资源
    最近更新 更多