Понимание повышения в обработке исключений Python

#python #exception #exception-handling

#python #исключение

Вопрос:

Что делает raise при обработке исключения python?

Я получил некоторый код

 def func():
  try :
    'some code here'
  except Exception, e:
     some_issue_entry(False, ke)
     db_entry(False, ke)
     raise

  except KeyboardInterrupt, ke:
     some_issue_entry(False, ke)
     db_entry(False, ke)
     raise

  some_issue_entry(True, None)
  db_entry(True, None)
  

Итак, вот этот код, который я собирался заменить, потому что я не хочу писать тот же код, который является обычной функцией с другим аргументом:

 def func():
  success, exec = True, None
  try :
    'some code here'
  except Exception, e:
     success, exec = False, e

  except KeyboardInterrupt, ke:
     success, exec = False, ke

  some_issue_entry(success, exec)
  db_entry(success, exec)

  if not success:
     raise
  

Вот мой запрос:

  1. как просто raise обрабатывать исключение и дифференцировать. Потому что он создает правильное исключение с использованием первого стиля. Выбирает ли он из локально сохраненного исключения?

  2. при использовании второго стиля также работает (не протестировано полностью), хотя я понятия не имею, почему, потому что я предполагаю, что raise связано с try, за исключением only. Безопасно ли использовать второй стиль.

Комментарии:

1. docs.python.org/3.4/tutorial/errors.html#raising-exceptions

Ответ №1:

Python сохраняет последнее пойманное исключение с текущим контекстом потока. Таким образом, все, что raise нужно сделать, это снова получить это исключение:

 do_raise(PyObject *type, PyObject *value, PyObject *tb)
{
    if (type == NULL) {
        /* Reraise */
        PyThreadState *tstate = PyThreadState_GET();
        type = tstate->exc_type == NULL ? Py_None : tstate->exc_type;
        value = tstate->exc_value;
        tb = tstate->exc_traceback;
        Py_XINCREF(type);
        Py_XINCREF(value);
        Py_XINCREF(tb);
    }
  

где PyThreadState_GET() просматривается текущий контекст потока.

Это задокументировано в raise документации по операторам:

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

Здесь область — это целая функция, а не только except набор.