Техническое собеседование
Задача:
Создайте декоратор retry, который повторяет выполнение функции заданное количество раз, если она завершилась с ошибкой. Если все попытки неудачны, декоратор должен вернуть сообщение об ошибке или выбросить исключение.
Условия:
- Декоратор принимает два аргумента:
- количество попыток retries;
- время ожидания между попытками delay (в секундах).
- Декорируемая функция может принимать любые аргументы и возвращать результат или выбрасывать исключение.
- Декоратор должен перехватывать исключения и повторять выполнение функции, если она завершилась с ошибкой.
Ожидаемый вывод (зависит от времени выполнения, поскольку ошибка случайная) для retries=5, delay=2:
Попытка 1 не удалась: Случайная ошибка. Повтор через 2 секунд.
Попытка 2 не удалась: Случайная ошибка. Повтор через 2 секунд.
Попытка 3 не удалась: Случайная ошибка. Повтор через 2 секунд.
Попытка 4 не удалась: Случайная ошибка. Повтор через 2 секунд.
Успех!
TypeError: retry.<locals>.my_decorator.<locals>.wrapper() missing 1 required positional argument: 'func'
Мое решение:
import time
from functools import wraps
# Мое решение
def retry(delay: int, retries: int):
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(1, retries+1):
try:
result = func(*args, **kwargs)
except Exception as e:
print(f"Попытка {attempt} не удалась: {e}. Повтор через {delay} секунд.")
time.sleep(delay)
else:
return result
return wrapper
return my_decorator
# Код для проверки
@retry(retries=5, delay=2)
def unstable_function():
if time.time() % 2 > 1.5:
raise ValueError("Случайная ошибка")
return "Успех!"
print(unstable_function())
Их решение:
def retry(retries=3, delay=1):
def decorator(func):
def wrapper(*args, **kwargs):
attempts = 0
while attempts < retries:
try:
return func(*args, **kwargs)
except Exception as e:
attempts += 1
print(f"Попытка {attempts} не удалась: {e}. Повтор через {delay} секунд.")
time.sleep(delay)
print(f"Функция {func.__name__} завершилась неудачно после {retries} попыток.")
return None
return wrapper
return decorator