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

Перестройка исключения python. Который поймать?

Я изучаю использование python. Я только что наткнулся на эту статью: http://nedbatchelder.com/blog/200711/rethrowing_exceptions_in_python.html Он описывает повторные исключения в python, например:

try:
    do_something_dangerous()
except:
    do_something_to_apologize()
    raise

С тех пор, как вы перебросили исключение, вы должны быть оператором "external catch-except". Но теперь я думал. Что делать, если do_something_to_apologize() внутри исключения выдает ошибку. Какой из них будет пойман во внешнем "уловке"? Тот, который вы переворачиваете, или тот, который был брошен do_something_to_apologize()? Или сначала будет обнаружено исключение с наивысшим приоритетом?

4b9b3361

Ответ 1

Попробуйте и посмотрите:

def failure():
    raise ValueError, "Real error"

def apologize():
    raise TypeError, "Apology error"

try:
    failure()
except ValueError:
    apologize()
    raise

Результат:

Traceback (most recent call last):
  File "<pyshell#14>", line 10, in <module>
    apologize()
  File "<pyshell#14>", line 5, in apologize
    raise TypeError, "Apology error"
TypeError: Apology error

Причина: "реальная" ошибка из исходной функции уже была захвачена except. apologize вызывает новую ошибку до достижения raise. Следовательно, raise в предложении except никогда не выполняется, и только ошибка извинения распространяется вверх. Если apologize вызывает ошибку, Python не знает, что после apologize вы создадите другое исключение.

Обратите внимание, что в Python 3 в traceback будут указаны оба исключения, с сообщением, объясняющим, как возникла вторая:

Traceback (most recent call last):
  File "./prog.py", line 9, in <module>
  File "./prog.py", line 2, in failure
ValueError: Real error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./prog.py", line 11, in <module>
  File "./prog.py", line 5, in apologize
TypeError: Apology error

Однако второе исключение (исключение "извинения" ) по-прежнему остается единственным, которое распространяется наружу и может быть захвачено предложением except более высокого уровня. Исходное исключение упоминается в трассировке, но добавляется в более поздний и больше не может быть обнаружено.

Ответ 2

Исключение, вызванное do_something_to_apologize(), будет обнаружено. Строка, содержащая рейз, никогда не будет запущена из-за исключения, вызванного do_something_to_apologize. Кроме того, я не верю, что в исключениях python есть понятие "приоритет".