If you want to pass kwargs
to decorators you need to do something like this (Decorators with parameters). To quote one of the answer's there:
@decorator_with_args(arg)
def foo(*args, **kwargs):
pass
Translates to:
foo = decorator_with_args(arg)(foo)
Simple decorators typically look like this:
def decorator(func):
def wrapper(*args, **kwargs):
returned_value = func(*args, **kwargs)
return returned_value
return wrapper
Here's a working demo for the behavior you want:
import time
import logging
from functools import wraps
def retry(**fkwargs):
def _decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(1, 6):
try:
return func(*args, **kwargs)
except Exception as e:
logging.warning("Error: {}, Attempt: {}, "
"Python Error: {}".format(fkwargs['error'], attempt, e))
time.sleep(1)
print("More than 5 attempts, closing the program")
# sys.exit(1)
return wrapper
return _decorator
@retry(error="My custom error")
def mock():
raise ValueError("Connection Error")
>>> mock()
WARNING:root:Error: My custom error, Attempt: 1, Python Error: Connection Error
WARNING:root:Error: My custom error, Attempt: 2, Python Error: Connection Error
WARNING:root:Error: My custom error, Attempt: 3, Python Error: Connection Error
WARNING:root:Error: My custom error, Attempt: 4, Python Error: Connection Error
WARNING:root:Error: My custom error, Attempt: 5, Python Error: Connection Error
More than 5 attempts, closing the program
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…