Рубрики
Без рубрики

Обработка исключений

Автор оригинала: 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 – Модуль для работы с трассировками