如何检测装饰器中缺少的参数?

How to detect missing arguments in decorator?

我想定义一个带有参数的装饰器,如果缺少该参数则会引发错误。

这是对简化示例的幼稚尝试:

def decorator_with_arg(a=None):

    if a is None :
        raise ValueError("Missing argument in decorator")

    def decorator(func):

        def wrapped_func(x):
            return func(x+ a)

        return wrapped_func

    return decorator

但是当我在没有参数的情况下使用这个装饰器时,它没有引发任何错误:

@decorator_with_arg
def simple_func(x):
    return 2*x

simple_func(1)

如何引发异常?

你没有正确使用装饰器,在你的代码中 simple_func(1) 只会 return wrapped_func,因为 @decorator_with_arg 只会做:

simple_func = decorator_with_arg(simple_func)
#                                ^ this is passing a=simple_func
# now simple_func is the decorator function defined inside decorator_with_arg

您需要 调用 您的 decorator_with_arg 以使其 return decorator 然后将用于修饰函数:

@decorator_with_arg(100)
def simple_func(x):
    return 2*x

print(simple_func(1)) # 202

无论如何,如果你想让一个参数成为强制参数,只需声明它而不用默认值:

def decorator_with_arg(a):
    # ...

并删除 if a is None 检查。


如果您想避免使用 @decorator_with_arg 而不是 @decorator_with_arg() 的错误,您可以添加检查以确保 a 不是函数:

def decorator_with_arg(a):
    if callable(a):
        raise TypeError("Incorrect use of decorator")
    
    def decorator(func):
        def wrapped_func(x):
            return func(x + a)
        return wrapped_func
    return decorator


@decorator_with_arg
def func():
    return 1
# TypeError: Incorrect use of decorator


@decorator_with_arg(123)
def func():
    return 1
# All fine