当我使用带参数的python装饰器时,如何将参数传递给最内层的函数?

时间:2018-07-02 00:58:42

标签: python decorator

这是我的装饰器,当func返回值不是True时,它会调用func

def deco_retry(retry_times):
    def _deco_retry(func):
        def wrapper(*args, **kwargs):
            while retry_times > 0:
                ret = func(*args, **kwargs)
                if ret:
                    return ret
                retry_times -= 1
        return wrapper
    return _deco_retry

@deco_retry(retry_times=1)
def func(ok=1):
    if ok == 1:
        return True
    else:
        return False

当我调用func()时,发生了错误:

Traceback (most recent call last):
  File "E:/Charles/Code/pycharmprj/Huobi/test_code/decorator_test.py", line 26, in <module>
    func()
  File "E:/Charles/Code/pycharmprj/Huobi/test_code/decorator_test.py", line 10, in wrapper
    while retry_times > 0:
UnboundLocalError: local variable 'retry_times' referenced before assignment

为什么我不能在最里面的函数中引用retry_times:包装器,我该如何纠正此错误?

1 个答案:

答案 0 :(得分:2)

这是因为稍后您将在函数中使用retry_times重新分配retry_times -= 1,从而使其成为局部变量。

您可以在while循环的正上方添加nonlocal(如果是python3):

def _deco_retry(func):
    def wrapper(*args, **kwargs):
        nonlocal retry_times
        while retry_times > 0:

或者您可以尝试使用while进行循环,而不是使用range循环:

def wrapper(*args, **kwargs):
    for _ in range(retry_times):
        ret = func(*args, **kwargs)
        if ret:
            return ret

应该相同,并且您不必加/减重试次数。