Перехват исключений в Python помогает уменьшить количество возникающих в программе сбоев. Таким образом, ваш код становится более надежным, а пользователям становится проще с ним работать. В этой статье я расскажу, как перехватывать несколько исключений в одном блоке try/except в Python.
1. Что такое исключения в Python?
В Python исключения – это механизм взаимодействия различных частей программы. Этот механизм позволяет одной части системы уведомлять о том, что она столкнулась с некой критической ошибкой и не знает, как с ней справиться.
В таком случае вызывается исключение. Другая часть программы, которая знает, как справиться с этой ошибкой, перехватывает это исключение и выполняет ее обработку надлежащим образом.
Если исключения не обработать, это может привести к сбою программы. Так что, обработка исключений позволяет уберечь вашу программу от сбоя и сделать ее более надежной.
Важность обработки нескольких исключений в Python
- Это помогает избежать дублирования кода, так как несколько исключений обрабатываются одним и тем же блоком. Это также упрощает чтение, редактирование и удаление кода.
- Кроме того, это помогает писать более эффективный код, так как тип ошибки нужно проверять не несколько, а лишь один раз.
2. Обработка нескольких исключений
Перехват нескольких исключений означает, что несколько исключений перехватываются одним и тем же блоком except. В Python вы можете перехватывать разные исключения отдельными блоками.
Или же, если вы хотите обрабатывать исключения вместе, вы можете обрабатывать их с помощью одного блока. Для этого вам нужно будет перехватить сразу несколько исключений. Здесь я расскажу и покажу на примере, как это можно сделать.
#1. Перехват разных исключений разными блоками
Допустим, что у нас есть программа, которая принимает на вход два различных числа и делит их друг на друга. В этой программе мы предполагаем, что, когда пользователь будет вводить недопустимые значения, будут возникать различные типы исключений. Так, в частности мы собираемся обрабатывать исключения ValueError и ZeroDivisionError.
Исключение ValueError будет вызываться тогда, когда пользователь будет вводить значение, которое невозможно преобразовать в целое число. А исключение ZeroDivisionError будет вызываться тогда, когда второе вводимое число будет равно нулю. И там, и там мы будем отображать сообщение об ошибке, которое гласит: «Вы ввели недопустимое значение» (You entered an invalid value).
Чтобы реализовать все, что мы описали выше, напишем следующий код:
try:
dividend = int(input('Enter first num: '))
divisor = int(input('Enter second num: '))
quotient = dividend / divisor
print(quotient)
except ValueError as e:
print("You entered an invalid value")
except ZeroDivisionError as e:
print("You entered an invalid value")
except Exception as e:
print("Something went wrong")
Если мы запустим этот код и введем текст, который нельзя преобразовать в целое число, то получим следующий результат:
Если же мы введем в качестве второго числа ноль, то получим вот такой результат:
Код работает ровно так, как мы и ожидали, но обратите внимание, что мы обрабатываем исключения ValueError и ZeroDivisionError одинаково. Получается, что мы практически дублируем блоки except. Это далеко от идеала, так как мы нарушаем один из принципов программирования – DRY (Don’t Repeat Yourself – Не повторяйся).
Так что, вместо того, чтобы писать два отдельных блока, мы можем объединить их в один, который будет перехватывать несколько исключений. Если мы это сделаем, то сможем избежать повторов.
#2. Перехват нескольких исключений в одном блоке except
Для того, чтобы перехватить несколько исключений, мы выделяем кортеж, в котором указаны все ошибки, которые мы хотим перехватить. Вот пример, где мы перехватываем в одном блоке except два исключения - ValueError и ZeroDivisionError:
try:
dividend = int(input('Enter first num: '))
divisor = int(input('Enter second num: '))
quotient = dividend / divisor
print(quotient)
except (ValueError, ZeroDivisionError) as e:
print("You entered an invalid value")
except Exception as e:
print("Something went wrong")
Эта реализация намного лучше, чем предыдущий код. По сути, это и есть обработка нескольких исключений. Код, который приведен выше, работает аналогично предыдущему. Так что, если вы тестируете его, используя предыдущие примеры, все должно работать как раньше:
#3. Определяем, какое исключение было перехвачено
Приведенный выше код выполняет первый блок except, когда обнаружена ошибка ValueError или ZeroDivisionError. В некоторых случаях возможно такое, что вы хотите выполнить какой-то код для обеих ошибок и какой-то еще код только для одной из них.
В таком случае для начала нужно определить, какая ошибка была перехвачена, после чего выполнить соответствующий код.
Для того, чтобы определить, какое исключение было перехвачено, вы можете добавить внутрь блока except блок if/else. Вот пример:
try:
dividend = int(input('Enter first num: '))
divisor = int(input('Enter second num: '))
quotient = dividend / divisor
print(quotient)
except (ValueError, ZeroDivisionError) as e:
print("You entered an invalid value")
if isinstance(e, ValueError):
print('Value Error')
else:
print('Zero Division Error')
except Exception as e:
print("Something went wrong")
Здесь, помимо того, что для ValueError и ZeroDivisionError мы печатаем сообщение об ошибке, мы также проверяем, ошибку какого типа мы обнаружили, и печатаем еще одно сообщение. Если мы запустим код еще раз, мы увидим дополнительное сообщение, касающееся перехваченного исключения.
3. Когда необходимо обрабатывать несколько исключений?
В общем случае обработка нескольких исключений идеально подходит, если вы хотите выполнить один и тот же код для похожих исключений, например,
- Сетевые запросы, которые не удалось выполнить по разным причинам. Независимо от причины, вы можете уведомить пользователя о том, что сервер на данный момент недоступен.
- Сбои соединения с базой данных, которые могут привести к ряду ошибок. И несмотря на то, что эти ошибки могут быть разными, принцип их обработки может быть одинаковый.
- Файловый ввод-вывод также может вызывать ошибки, которые можно обрабатывать одинаково, например, ошибки прав доступа или ошибки записи на диск.
Заключение
В этой статье мы рассмотрели, как можно объединить несколько блоков except в один, одновременно перехватывая несколько исключений. Это может помочь вам сделать ваш код более читабельным и удобным в сопровождении.