python - 如何在不使用 @ 语法的情况下使用 "double layered"装饰器?

标签 python python-3.x decorator wrapper

假设我有这个装饰器:

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'

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

我知道,如果它只是一个单层装饰器(即没有参数的装饰器),那么您可以将其包装在装饰器函数中,如下所示:

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

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

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

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

最佳答案

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)

关于python - 如何在不使用 @ 语法的情况下使用 "double layered"装饰器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52908813/

相关文章:

python - CSV Reader 对象获取 ValueError : I/O operation on closed file?

python - 在 Tkinter 中隐藏 TreeView 列

python - 类方法的最小装饰器

python - 调用修饰的外部函数

python - 修改django装饰器函数,Permissionn_required

python - python package namespaces : z3c, zc, collective 背后是什么?

python - 编写一个使用 *args 添加列表元素的函数

python - 从 xarray 中选择一列

python-3.x - 在 Yocto 中更改区域设置

python - 如何使用函数打破循环