Как выполнить что-то, если произойдет исключение - PullRequest
9 голосов
/ 11 ноября 2010

Вопрос новичка на Python: мне нужно сделать следующее

try:
  do-something()
except error1:
  ...
except error2:
  ...
except:
  ...
#Here I need to do something if any exception of the above exception was thrown.

Я могу установить флаг и сделать это.Но есть ли более чистый способ сделать это?

Ответы [ 6 ]

3 голосов
/ 12 ноября 2010

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

Вот небольшой интерактивный пример (смоделированный на Applesoft BASIC для целей ностальгии).

try:
    input("]")  # for Python 3: eval(input("]"))
except:
    try:
       raise
    except SyntaxError:
       print "?SYNTAX",
    except ValueError:
       print "?ILLEGAL QUANTITY",
    # additional handlers here
    except:
       print "?UNKNOWN",
    finally:
       print "ERROR"
2 голосов
/ 11 ноября 2010

Я только что опробовал несколько разных идей, и похоже, что ваш лучший выбор - флаг

  • else suite вызывается только если исключений нет
  • наконец всегда будет называться
1 голос
/ 05 сентября 2012

На самом деле я не люблю флаги и считаю их последним решением. В этом случае я бы рассмотрел что-то вроде этого:

def f():
  try:
    do_something()
  except E1:
    handle_E1()
  except E2:
    handle_E2()
  else:
    return
  do_stuff_to_be_done_in_case_any_exception_occurred()

Конечно, это только вариант, если вы можете вернуться в случае else:.

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

def f():
  try:  # general error handling
    try:  # specific error handling
      do_something()
    except E1:
      handle_E1()
      raise
    except E2:
      handle_E2()
      raise
  except (E1, E2):
    do_stuff_to_be_done_in_case_any_exception_occurred()
1 голос
/ 11 ноября 2010

Из документов: http://docs.python.org/reference/compound_stmts.html#finally

Если наконец присутствует, он определяет обработчик очистки. Предложение try выполняется, в том числе любые исключения и другие. Если исключение возникает в каком-либо из пунктов и не обрабатывается, исключение временно сохраняется. Предложение finally выполняется. Если есть сохраненное исключение, оно повторно вызывается в конце предложения finally. Если предложение finally вызывает другое исключение или выполняет оператор return или break, сохраненное исключение теряется. Информация об исключении недоступна программе во время выполнения предложения finally.

0 голосов
/ 11 ноября 2010

Это лучший способ, который я могу придумать. Выглядит как запах кода, хотя

try:
  exception_flag = True
  do-something()
  exception_flag = False
except error1:
  ...
except error2:
  ...
except:
  ...
finally:
  if exception_flag:
    ...

Вам не понадобится finally, если вы не вызываете исключения в обработчике

0 голосов
/ 11 ноября 2010

Непонятно, нужно ли вам по-разному обрабатывать error1, error2 и т. Д. Если нет, то следующий код поможет:

try:
    do_something()
except (error1, error2, error3), exception_variable:
    handle_any_of_these_exceptions()

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

    if isinstance(exception_variable, error1):
       do_things_specific_to_error1()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...