Автор оригинала: Doug Hellmann.
sys
включает функции для перехвата и работы с исключениями.
Необработанные исключения
Многие приложения структурированы с помощью основного цикла, который завершает выполнение в глобальном обработчике исключений для перехвата ошибок, не обрабатываемых на более низком уровне. Другой способ добиться того же – установить в sys.excepthook
функцию, которая принимает три аргумента (тип ошибки, значение ошибки и трассировку) и позволяет ей обрабатывать необработанные ошибки.
sys_excepthook.py
import sys def my_excepthook(type, value, traceback): print('Unhandled error:', type, value) sys.excepthook my_excepthook print('Before exception') raise RuntimeError('This is the error message') print('After exception')
Поскольку вокруг строки, в которой возникает исключение, нет блока try: except
, следующий вызов print ()
не выполняется, даже если исключение
$ python3 sys_excepthook.py Before exception Unhandled error:This is the error message
Текущее исключение
Бывают случаи, когда явный обработчик исключений предпочтителен либо для ясности кода, либо во избежание конфликтов с библиотеками, которые пытаются установить свой собственный excepthook
. В этих случаях можно создать общую функцию-обработчик, для которой не требуется явно передавать объект исключения, вызывая exc_info ()
для получения текущего исключения для потока.
Возвращаемое значение exc_info ()
– это трехчленный кортеж, содержащий класс исключения, экземпляр исключения и трассировку. Использование exc_info ()
предпочтительнее
sys_exc_info.py
import sys import threading import time def do_something_with_exception(): exc_type, exc_value sys.exc_info()[:2] print('Handling {} exception with message "{}" in {}'.format( exc_type.__name__, exc_value, threading.current_thread().name)) def cause_exception(delay): time.sleep(delay) raise RuntimeError('This is the error message') def thread_target(delay): try: cause_exception(delay) except RuntimeError: do_something_with_exception() threads [ threading.Thread(targetthread_target, args(0.3,)), threading.Thread(targetthread_target, args(0.1,)), ] for t in threads: t.start() for t in threads: t.join()
В этом примере избегается введение круговой ссылки между объектом трассировки и локальной переменной в текущем кадре, игнорируя эту часть возвращаемого значения из exc_info ()
. Если трассировка необходима (например, чтобы ее можно было записать в журнал), явно удалите локальную переменную (используя del
), чтобы избежать циклов.
$ python3 sys_exc_info.py Handling RuntimeError exception with message "This is the error message" in Thread-2 Handling RuntimeError exception with message "This is the error message" in Thread-1
Предыдущее интерактивное исключение
В интерактивном интерпретаторе есть только один поток взаимодействия. Необработанные исключения в этом потоке сохраняются в трех переменных в sys
( last_type
, last_value
и last_traceback
), чтобы сделать их легко получить для отладки. Использование посмертного отладчика в pdb позволяет избежать необходимости использовать значения напрямую.
$ python3 Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 5 2014, 20:42:22) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> def cause_exception(): ... raise RuntimeError('This is the error message') ... >>> cause_exception() Traceback (most recent call last): File "", line 1, in File " ", line 2, in cause_exception RuntimeError: This is the error message >>> import pdb >>> pdb.pm() > (2)cause_exception() (Pdb) where (1) () > (2)cause_exception() (Pdb)
Смотрите также
исключения
– встроенные ошибки.- pdb – отладчик Python
- traceback – Модуль для работы с трассировками