Оберните вызов функции циклом while True с try/except и возвращайте результат при успехе. Перехватывайте обычные Exception, сохраняя возможность остановки через KeyboardInterrupt и SystemExit.
Декоратор, автоматически пере вызывающий функцию после исключения
Оберните вызов функции циклом while True с try/except и возвращайте результат при успехе. Перехватывайте обычные Exception, сохраняя возможность остановки через KeyboardInterrupt и SystemExit.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Создайте декоратор, который будет бесконечно повторять вызов функции, если при её исполнении возникнет исключение. Декоратор должен перехватывать любые исключения, выводить их (по желанию) и снова вызывать оригинальную функцию, пока она не завершится без ошибок.
@repeat_on_error
def my_func():
# тело функции, которое может бросать исключения
...
Требования:
- Декоратор не принимает дополнительных параметров.
- При каждом возникновении исключения функция должна запускаться заново.
- Цикл повторов продолжается бесконечно, пока функция не выполнится успешно.
- При необходимости можно добавить логирование ошибки перед повторным запуском.
Ответ
Оберните вызов функции циклом while True с try/except и возвращайте результат при успехе. Перехватывайте обычные Exception, сохраняя возможность остановки через KeyboardInterrupt и SystemExit.
Вариант для синхронных функций:
from functools import wraps
import time
def repeat_on_error(func):
@wraps(func)
def wrapper(*args, **kwargs):
while True:
try:
return func(*args, **kwargs)
except Exception:
time.sleep(0.1)
return wrapper
Небольшая пауза предотвращает непрерывный горячий цикл. Буквальный перехват BaseException захватил бы и команды остановки, поэтому здесь намеренно обрабатываются обычные ошибки. Для production обычно нужны предел попыток, backoff и идемпотентность операции: бесконечное повторение может дублировать внешние действия. Для async-функций требуется отдельная обёртка с await.