Как сделать так, чтобы декоратор повторов указывал на использованные все попытки? - PullRequest
0 голосов
/ 08 января 2019

Я реализовал декоратор повторов в своем коде, но хотел бы как-то указать, когда он использовал все свои попытки. Как я могу это сделать?

Я использую Повторяющийся декоратор 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 голосов
/ 08 января 2019

Вы можете поймать исключение 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!'
...