Блок try-exc: аналог для else, если возникла исключительная ситуация
У меня есть такой код:
try:
return make_success_result()
except FirstException:
handle_first_exception()
return make_error_result()
except SecondException:
handle_second_exception()
return make_error_result()
И мне интересно, есть ли способ добиться этого:
try:
# do something
except Error1:
# do Error1 specific handling
except Error2:
# do Error2 specific handling
else:
# do this if there was no exception
????:
# ALSO do this if there was ANY of the listed exceptions (e.g. some common error handling)
Таким образом, код выполняется в одной из следующих последовательностей:
try > else > finally
try > except > ???? > finally
РЕДАКТИРОВАТЬ: моя точка зрения здесь
????
блок должен выполняться сразу после ЛЮБОГО изexcept
блоки, что означает, что это дополнение к обработке ошибок, а не замена.
5 ответов
В этом случае я бы установил логическое значение, когда вы получите исключение, например:
got_exception = False
try:
# do something
except Error1:
# do Error1 specific handling
got_exception = True
except Error2:
# do Error2 specific handling
got_exception = True
else:
# If there was no exception
finally:
if got_exception:
# ALSO do this if there was ANY exception (e.g. some common error handling)
Это должно соответствовать вашим потребностям, что является IMO самым чистым способом объединения всех решений, которые были представлены, в наиболее читаемую структуру кода, которая будет легче всего отлаживать.
Ты можешь сделать:
try:
# Do something
except Error1:
# Do Error1 specific handling
except Error2:
# Do Error2 specific handling
except Exception:
# Handle any other exception (Generic exception handling)
else:
# Do this if there were no exceptions
finally:
# Execute this regardless
Вы действительно можете сделать это:
try:
print 'try'
# 1/0
# {}[1]
# {}.a
except AttributeError, KeyError: # only handle these exceptions..
try:
raise # re-raise the exception so we can add a finally-clause executing iff there was an exception.
except AttributeError:
print 'attrerr'
# raise ... # any raises here will also execute 'common'
except KeyError:
print 'keyerror'
finally: # update 0: you wanted the common code after the exceptions..
print "common"
else:
print 'no exception'
но это ужасно, и я бы не советовал вам обойтись без обильного количества комментариев, объясняющих почему..
ОБНОВЛЕНИЕ: вам не нужно ничего ловить, кроме интересных исключений во внутреннем блоке try. Код обновлен.
ОБНОВЛЕНИЕ 2: за разъяснения ОП, common
должен быть выполнен, когда выдается интересное исключение. Код обновлен. Версия @MattTaylor определенно подходит;-)
Да, обработка исключений в Python включает в себя как else
и finally
пункт. Вы можете сделать это:
try:
# do something
except Error1:
# do Error1 specific handling
except Error2:
# do Error2 specific handling
else:
# do this if there was no exception
finally:
# Do this in any case!
Документы Python упоминают эти блоки, хотя и не показывают полный пример, который вам нужен.
РЕДАКТИРОВАТЬ: я вижу, что вы не просите конкретно для очистки в общем случае. Документы Python говорят об этом так:
У оператора try есть еще одно необязательное предложение, предназначенное для определения действий по очистке, которые должны выполняться при любых обстоятельствах.
Обратите внимание, что finally
будет работать независимо от того, было ли исключение или нет. В сочетании с else
блок, вы все равно должны быть в состоянии делать то, что вы хотите.
Вы можете перехватить все ошибки и проверить их тип в коде обработки ошибок следующим образом:
try:
# do something
except Exception as e:
if isinstance(e, Error1):
# do Error1 specific handling
elif isinstance(e, Error2):
# do Error2 specific handling
else:
# do non-Error1/Error2 handling
# ALSO do this if there was ANY exception (e.g. some common error handling)
else:
# do this if there was no exception