У меня есть предложение try
/finally
в моем script. Возможно ли получить точное сообщение об ошибке из предложения finally
?
Могу ли я получить исключение из блока finally в python?
Ответ 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>)
Надеюсь, это все упростит.
Ответ 4
Вы захотите сделать это в предложении except, а не в конце.
Обратитесь к: http://www.doughellmann.com/articles/Python-Exception-Handling/