2015-12-08 6 views
0

Возможно ли использовать диспетчер контекста для выполнения блока кода и продолжать его повторную попытку, если он генерирует конкретное исключение. Что-то вроде этого:Контекстный менеджер для повторного блока после исключения

with RetryOnException(Some.Exception): 
    obj.doit() 

Какой бы эквивалент:

while True: 
    try: 
     obj.doit() 
    except Some.Exception: 
     logger.exception("failed") 
     time.sleep(1) 
    else: 
     break 

У меня есть много вызовов к способу, который может бросить исключение, и было бы очень неудобно иметь, чтобы написать все, что каждый раз.

ответ

0

Нет, менеджер контекста не способен выполнять итерацию по содержащемуся в нем коду. Для того, чтобы сделать что-то подобное тому, что ваш требуйте:

def retry(f, on_exception=None, exception_type=Exception): 
    # a default exception handler 
    on_exception = on_exception or lambda e: pass 

    while True: 
     try: 
      return f() 
     except exception_type as e: 
      on_exception(e) 

Тогда вы могли бы назвать это как, например:

def my_handler(e): 
    logger.exception("failed") 
    time.sleep(1) 

retry(obj.doit, on_exception=my_handler) 

Или более кратко в этом случае просто:

retry(obj.doit, lambda e: logger.exception("failed"), time.sleep(1))