На этом шаге мы рассмотрим еще несколько особенностей обработки исключений.
Для получения информации об исключении можно воспользоваться функцией exc_info() из модуля sys, которая возвращает кортеж из трех элементов: типа исключения, значения и объекта с трассировочной информацией. \ Преобразовать эти значения в удобочитаемый вид позволяет модуль traceback. Пример использования функции exc_info() и модуля traceback:
import sys, traceback try: x = 1 / 0 except ZeroDivisionError: Type, Value, Trace = sys.exc_info() print ("Type: ", Type) print ("Value:", Value) print ("Trace:", Trace) print ("\n", "print_exception()".center (40, "-") ) traceback.print_exception(Type, Value, Trace, limit=5, file=sys.stdout) print ("\n", "print_tb()".center(40, "-")) traceback.print_tb(Trace, limit=1, file=sys.stdout) print ("\n", "format_exception()".center(40, "-")) print (traceback.format_exception(Type, Value, Trace, limit=5)) print ("\n", "format_exception_only()".center(40, "-")) print (traceback.format_exception_only(Type, Value))
Результат работы приложения:
Type:
Value: division by zero
Trace:
-----------print_exception()------------
Traceback (most recent call last):
File "C:\Python34\Files\pr149_1.py", line 3, in
x = 1 / 0
ZeroDivisionError: division by zero
---------------print_tb()---------------
File "C:\Python34\Files\pr149_1.py", line 3, in
x = 1 / 0
-----------format_exception()-----------
['Traceback (most recent call last):\n', '
File "C:\\Python34\\Files\\pr149_1.py", line 3,
in \n x = 1 / 0\n', 'ZeroDivisionError: division by zero\n']
--------format_exception_only()---------
['ZeroDivisionError: division by zero\n']
Если в инструкции except не указан класс исключения, то такой блок перехватывает все исключения. На практике следует избегать пустых инструкций except, т. к. можно перехватить исключение, которое является лишь сигналом системе, а не ошибкой. Пример пустой инструкции except:
try: х = 1 / 0 # Ошибка деления на 0 except: # Обработка всех исключений х = 0 print(х) # Выведет: 0
Результат работы приложения:
0
Если в обработчике присутствует блок else, то инструкции внутри этого блока будут выполнены только при отсутствии ошибок. При необходимости выполнить какие-либо завершающие действия вне зависимости от того, возникло исключение или нет, следует воспользоваться блоком finally. Для примера выведем последовательность выполнения блоков:
try: #х = 10 / 2 # Нет ошибки х = 10 / 0 # Ошибка деления на 0 except ZeroDivisionError: print("Деление на 0") else: print("Блок else") finally: print("Блок finally")
Результат выполнения при отсутствии исключения:
Блок else
Блок finally
Последовательность выполнения блоков при наличии исключения будет другой:
Деление на 0
Блок finally
Необходимо заметить, что при наличии исключения и отсутствии блока except инструкции внутри блока finally будут выполнены, но исключение не будет обработано. Оно продолжит "всплывание" к обработчику более высокого уровня. Если пользовательский обработчик отсутствует, то управление передается обработчику по умолчанию, который прерывает выполнение программы и выводит сообщение об ошибке. Пример:
>>> try: x = 10 / 0 finally: print ("Блок finally") Блок finally Traceback (most recent call last): File "<pyshell#3>", line 2, in <module> x = 10 / 0 ZeroDivisionError: division by zero
В качестве примера переделаем программу из 30 шага, которая находит сумму произвольного количества целых чисел, введенных пользователем, таким образом, чтобы при вводе строки вместо числа программа не завершалась с фатальной ошибкой:
# -*- coding: utf-8 -*- print ("Введите слово 'stop' для получения результата") summa = 0 while True: x = input("Введите число: ") if x == "stop": break # Выход из цикла try: x = int(x) # Преобразуем строку в число except ValueError: print("Необходимо ввести целое число!") else: summa += x print ("Сумма чисел равна:", summa) input()
Процесс ввода значений и получения результата выглядит так (значения, введенные пользователем, выделены черным цветом):
Введите слово 'stop' для получения результата
Введите число: 10
Введите число: st
Необходимо ввести целое число!
Введите число: -5
Введите число:
Необходимо ввести целое число!
Введите число: stop
Сумма чисел равна: 5
На следующем шаге мы рассмотрим инструкцию with...as.