На этом шаге мы рассмотрим способы создания пользовательских исключений.
Для возбуждения пользовательских исключений предназначены две инструкции:
Инструкция raise возбуждает заданное исключение. Она имеет несколько вариантов формата:
raise <Экземпляр класса> raise <Название класса> raise <Экземпляр или название класса> from <Объект исключения> raise
В первом варианте формата инструкции raise указывается экземпляр класса возбуждаемого исключения. При создании экземпляра можно передать данные конструктору класса. Эти данные будут доступны через второй параметр в инструкции except. Пример возбуждения встроенного исключения ValueError:
>>> raise ValueError("Описание исключения") Traceback (most recent call last): File "<pyshell#5>", line 1, in <module> raise ValueError("Описание исключения") ValueError: Описание исключения
Пример обработки этого исключения:
>>> try: raise ("Описание исключения") except ValueError as msg: print(msg) # Выведет: Описание исключения Описание исключения
В качестве исключения можно указать экземпляр пользовательского класса:
class MyError(Exception): def __init__ (self, value): self.msg = value def __str__(self): return self.msg # Обработка пользовательского исключения try: raise MyError("Описание исключения") except MyError as err: print (err) # Вызывается метод __str__() print (err.msg) # Обращение к атрибуту класса # Повторно возбуждаем исключение raise MyError("Описание исключения")
Результат выполнения:
Описание исключения Описание исключения Traceback (most recent call last): File "C:\Python34\Files\152_1.py", line 13, inraise MyError("Описание исключения") MyError: Описание исключения
Класс Exception содержит все необходимые методы для вывода сообщения об ошибке. Поэтому в большинстве случаев достаточно создать пустой класс, который наследует класс Exception:
class MyError(Exception): pass try: raise MyError("Описание исключения") except MyError as err: print (err) # Выведет: Описание исключения
Результат выполнения:
Описание исключения
Во втором варианте формата инструкции raise в первом параметре задается объект класса, а не экземпляр. Пример;
>>> try: raise ValueError # Эквивалентно: raise ValueError() except ValueError: print("Сообщение об ошибке") Сообщение об ошибке
В третьем варианте формата инструкции raise в первом параметре задается экземпляр класса или просто название класса, а во втором параметре указывается объект исключения. В этом случае объект исключения сохраняется в атрибуте __cause__. При обработке вложенных исключений эти данные используются для вывода информации не только о последнем исключении, но и о первоначальном исключении. Пример:
>>> try: x = 1 / 0 except Exception as err: raise ValueError() from err
Traceback (most recent call last):
File "<pyshell#20>", line 2, in <module>
x = 1 / 0
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<pyshell#20>", line 4, in <module>
raise ValueError() from err
ValueError
Как видно из результата, мы получили информацию не только по исключению ValueError, но и по исключению ZeroDivisionError. Следует заметить, что при отсутствии инструкции from информация сохраняется неявным образом. Если убрать инструкцию from в предыдущем примере, то получим следующий результат:
Traceback (most recent call last):
File "<pyshell#22>", line 2, in <module>
x = 1 / 0
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#22>", line 4, in <module>
raise ValueError()
ValueError
Четвертый вариант формата инструкции raise позволяет повторно возбудить последнее исключение и обычно применяется в коде, следующем за инструкцией except. Пример:
class MyError(Exception): pass try: raise MyError("Сообщение об ошибке") except MyError as err: print (err) raise # Повторно возбуждаем исключение
Результат выполнения:
Сообщение об ошибке Traceback (most recent call last): File "C:\Python34\Files\152_3.py", line 3, in <module> raise MyError("Сообщение об ошибке") MyError: Сообщение об ошибке
Инструкция assert возбуждает исключение AssertionError, если логическое выражение возвращает значение False. Инструкция имеет следующий формат:
assert <Логическое выражение> [, <Данные>]
Инструкция assert эквивалентна следующему коду:
if __debug__: if not <Логическое выражение>: raise AssertionError(<Данные>)
Если при запуске программы используется флаг -O, то переменная __debug__ будет иметь ложное значение. Таким образом можно удалить все инструкции assert из байт-кода.
Пример использования инструкции assert
try: x = -3 assert x >= 0, "Сообщение об ошибке" except AssertionError as err: print(err) # Выведет: Сообщение об ошибке
Результат выполнения:
Сообщение об ошибке
Со следующего шага мы начнем рассматривать классы итераторов, контейнеров и перечислений.