Как несколько раз повторить блок Try Except
У меня есть функция, которая создает подключаение к устройству. Устройство может не ответить, тогда функция упадет с ошибкой. Как я могу в блоке try except реализовать 5 попыток подключения с интервалом в 1 секунду. То есть нужно сделать try, затем, если подключение успешно, программа идет дальше, а если не успешно, ждет секунду и снова try. И так 5 раз. Если на 5 раз поключение не успешно, тогда выводится сообщение об ошибке. Понятно, что можно сделать вложением одного блока try ecxept в другой, но не хотелось бы иметь целых 5 вложений. В голову приходит только что-то вот такое.
def get_result():
for i in range(5):
try:
connection = make_connection()
except:
if i == 4:
print('ошибка подключения')
return
else:
sleep(1)
else:
break
# и далее продолжение программы...
result = connection.read()
return result
Ответы (3 шт):
import time
counter = 0
while True:
try:
connection = make_connection()
except:
if counter > 5:
print('Ошибка подключения')
break
else:
counter += 1
time.sleep(1)
С использованием for:
for i in range(5):
try:
connection = make_connection()
break
except:
time.sleep(1)
else:
print('Ошибка подключения')
def get_result(retry=5):
try:
connection = make_connection()
except:
if retry:
sleep(1)
return get_result(retry-1)
else:
raise
result = connection.read()
return result
Красивое решение - использование декоратора @retry. Ваш код выполняете в виде функции и перед именем функции ставите декоратор @retry(num_retries=3, exception_to_check=ValueError, sleep_time=0)
К примеру что-то такое:
import random
import time
from functools import wraps
def retry(num_retries, exception_to_check, sleep_time=0):
"""
Decorator that retries the execution of a function if it raises a specific exception.
"""
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
for i in range(1, num_retries+1):
try:
return func(*args, **kwargs)
except exception_to_check as e:
print(f"{func.__name__} raised {e.__class__.__name__}. Retrying...")
if i < num_retries:
time.sleep(sleep_time)
# Raise the exception if the function was not successful after the specified number of retries
raise e
return wrapper
return decorate
@retry(num_retries=3, exception_to_check=ValueError, sleep_time=1)
def random_value():
value = random.randint(1, 5)
if value == 3:
raise ValueError("Value cannot be 3")
return value
random_value()
# random_value raised ValueError. Retrying...
# 1
random_value()
# 5
Взято отсюда https://vc.ru/u/1389654-machine-learning/604457-12-dekoratorov-python-kotorye-vyvedut-vash-kod-na-novyy-uroven Но можно и попроще взять отсюда https://habr.com/ru/companies/otus/articles/666016/
def retry(max_retries):
def retry_decorator(func):
def _wrapper(*args, **kwargs):
for _ in range(max_retries):
try:
func(*args, **kwargs)
except:
time.sleep(1)
return _wrapper
return retry_decorator
@retry(2)
def might_fail():
print("might_fail")
raise Exception