Код сначала падает: hello не принимает max_tries. Если требуется retry, внешняя функция должна принимать число попыток, а повторять вызов нужно только после оговорённой ошибки, не после успеха.
def hello(func):
Код сначала падает: hello не принимает max_tries. Если требуется retry, внешняя функция должна принимать число попыток, а повторять вызов нужно только после оговорённой ошибки, не после успеха.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
def hello(func): def decorator(func): def wrapper(a,b):
result = None
for _ in range(max_tries):
print('Привет')
result = func(a,b)
print("Пока")
return result
return wrapper
return decorator
@hello(max_tries=5) def add_numbers(a,b): return a+b
print(add_numbers(2,3))
Ответ
Код сначала падает: hello не принимает max_tries. Если требуется retry, внешняя функция должна принимать число попыток, а повторять вызов нужно только после оговорённой ошибки, не после успеха.
Ниже вариант с повтором только указанных исключений; для add_numbers повтор не потребуется:
from functools import wraps
def hello(max_tries, retry_on=(TimeoutError,)):
if max_tries < 1:
raise ValueError('max_tries must be positive')
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_tries):
print('Привет')
try:
return func(*args, **kwargs)
except retry_on:
if attempt == max_tries - 1:
raise
finally:
print('Пока')
return wrapper
return decorator
@hello(max_tries=5)
def add_numbers(a, b):
return a + b
print(add_numbers(2, 3))
Вывод: «Привет», «Пока», 5. Для внешних операций также нужны backoff и идемпотентность: повтор после timeout может дублировать уже выполненное действие.