How to pass parameters to the innermost function when i use python decorator with parameters? [duplicate]


How to pass parameters to the innermost function when i use python decorator with parameters? [duplicate]



This question already has an answer here:



here is my decorator for recall func when func return is not True


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



when i call func(), error occurred:


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



why can't i reference retry_times in the innermost function: wrapper, how can i correct this error?


retry_times



This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.





This has nothing to do with decorators. This is the standard problem of Python creating a local variable for any name that is assigned to within a function.
– melpomene
Jul 2 at 1:04





thank you! I know the reason that I create a new local variable
– Charles
Jul 2 at 5:51




1 Answer
1



This is because you are re-assigning retry_times later in the function with retry_times -= 1, hence making it a local variable.


retry_times


retry_times -= 1



You can add nonlocal (if python3) right above the while loop:


nonlocal


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



Or instead of using a while loop, you can try looping with range instead:


while


range


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



Should work the same, and you don't have to mess around with adding/subtracting the amount of retries.





Thank you very much, When I correct to the same as you, the problem was solved. and I know I am wrong because I created a new local variable.
– Charles
Jul 2 at 5:51

Popular posts from this blog

How to add background colour in existing image using Swift?

Moria Casán

How to make file upload 'Required' in Contact Form 7?