Декоратор оборачивает функцию, генератор выдаёт значения через yield. Retry-декоратор повторяет только ожидаемые временные ошибки и ограничивает число попыток.
Расскажите про декораторы и генераторы. Напишите декоратор retry с параметрами.
Декоратор оборачивает функцию, генератор выдаёт значения через yield. Retry-декоратор повторяет только ожидаемые временные ошибки и ограничивает число попыток.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Декоратор оборачивает функцию, генератор выдаёт значения через yield. Retry-декоратор повторяет только ожидаемые временные ошибки и ограничивает число попыток.
Синхронный пример: attempts включает первый запуск, последняя ошибка сохраняет traceback.
from functools import wraps
from time import sleep
def retry(attempts=3, delay=0.1, errors=(TimeoutError,)):
if attempts < 1 or delay < 0:
raise ValueError('Некорректные параметры')
def decorate(fn):
@wraps(fn)
def wrapped(*args, **kwargs):
for i in range(attempts):
try:
return fn(*args, **kwargs)
except errors:
if i == attempts - 1:
raise
sleep(delay * 2 ** i)
return wrapped
return decorate
В рабочем сервисе добавляют jitter и общий deadline. Повторять неидемпотентную операцию опасно. Для async нужны await и asyncio.sleep. Оборачивание генераторной функции не перехватывает ошибки, возникающие позже при переборе её значений.