如何让重试装饰器指示已使用所有重试?

时间:2019-01-08 18:18:01

标签: python python-decorators

我已经在代码中实现了重试装饰器,但想以某种方式指出何时使用了所有重试。我该怎么办?

我正在使用retrying decorator v1.3.3。

我尝试使用stop_func,但这似乎是按正常行为调用的,而不是重试。

我不确定如何从装饰器中调出尝试编号。

from retrying import retry

def _query_with_retries(self):
    _retriable_query = retry(stop_max_attempt_number=3,
                             wait_incrementing_start=50,
                             wait_incrementing_increment=10)(self._query)
    return _retriable_query()

当前,我的代码仅在上次重试时引发一般异常。我希望能够告知“所有重试已用尽”或类似的消息。

1 个答案:

答案 0 :(得分:3)

您可以捕获装饰器停止重试时引发的retrying.RetryError异常;在您自己的包装装饰器中执行此操作:

from functools import wraps
from retrying import retry, RetryError

def printing_retry(*args, **kwargs):
    def decorator(f):            
        decorated = retry(*args, **kwargs)(f)
        @wraps(decorated)
        def wrapper(*args, **kwargs):
            try:
                return decorated(*args, **kwargs)
            except RetryError:
                print("All retries have been used up")
                # optionally, re-raise the exception at this point
                # raise
        return wrapper
    if len(args) == 1 and callable(args[0]):
        return decorator(args[0])
    return decorator

此修饰符将替换代码中的@retry修饰符;当您调用修饰的函数时,它将捕获RetryError异常,该异常在该函数的尝试用尽时引发,并打印出一条消息。

如果您想将重试期间引发的任何异常包装在wrap_exception=True异常中,请记住设置RetryException

演示:

>>> @printing_retry(stop_max_attempt_number=1, wrap_exception=True)
... def do_something_unreliable():
...     if random.randint(0, 10) > 1:
...         raise IOError("Broken sauce, everything is hosed!!!111one")
...     else:
...         return "Awesome sauce!"
...
>>> do_something_unreliable()
All retries have been used up
>>> do_something_unreliable()
'Awesome sauce!'