Подтвердить что ты не робот

Могу ли я получить исключение из блока finally в python?

У меня есть предложение try/finally в моем script. Возможно ли получить точное сообщение об ошибке из предложения finally?

4b9b3361

Ответ 1

Нет, в finally время sys.exc_info - все-Нет, было ли исключение или нет. Использование:

try:
  whatever
except:
  here sys.exc_info is valid
  to re-raise the exception, use a bare `raise`
else:
  here you know there was no exception
finally:
  and here you can do exception-independent finalization

Ответ 2

Блок finally будет выполнен независимо от того, было ли выбрано исключение или нет, так как указывает Джош, вы, скорее всего, не захотите его обрабатывать.

Если вам действительно нужно значение исключения, которое было поднято, вы должны поймать исключение в блоке except и либо обработать его соответствующим образом, либо повторно поднять его, а затем использовать это значение в блоке finally - с ожиданием, что он, возможно, никогда не был установлен, если не было исключений, возникших во время исполнения.

import sys

exception_name = exception_value = None

try:
    # do stuff
except Exception, e:
    exception_name, exception_value = sys.exc_info()[:2]
    raise   # or don't -- it up to you
finally:
    # do something with exception_name and exception_value
    # but remember that they might still be none

Ответ 3

Собственно, другие ответы немного расплывчаты. Итак, позвольте мне пояснить это. Вы всегда можете вызывать sys.exc_info() из блока finally. Однако его выход будет зависеть от того, было ли исключение действительно поднято.

import sys

def f(i):

    try:
        if i == 1:
            raise Exception
    except Exception as e:
        print "except -> " + str(sys.exc_info())
    finally:
        print "finally -> " + str(sys.exc_info())

f(0)
f(1)

>>> 
finally -> (None, None, None)
except -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x029438F0>)
finally -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x029438F0>)

Таким образом, вы всегда можете узнать в блоке finally, независимо от того, было ли возбуждено исключение, если это функция первого уровня. Но sys.exc_info() будет вести себя по-разному, если длина стека вызовов превышает 1, как показано ниже. Для получения дополнительной информации см. Как работает sys.exc_info()?

import sys

def f(i):

    try:
        if i == 1:
            raise Exception
    except Exception as e:
        print "except -> " + str(sys.exc_info())
    finally:
        print "finally -> " + str(sys.exc_info())

def f1(i):
    if i == 0:
        try:
            raise Exception('abc')
        except Exception as e:
            pass

    f(i)

f1(0)
f1(1)

>>> 
finally -> (<type 'exceptions.Exception'>, Exception('abc',), <traceback object at 0x02A33940>)
except -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x02A33990>)
finally -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x02A33990>)

Надеюсь, это все упростит.