Работа с исключениям это отдельное искусство, освоив которое вы получите инструмент огромного потенциала. Я продемонстрирую несколько методов работы с исключениями в этой главе.
В конечном итоге, нас интересует синтаксис try/except
. Код, который может
вызвать исключение, помещается в try
блок, обработка исключения - в
except
. Простой пример:
try:
file = open('test.txt', 'rb')
except IOError as e:
print('Было вызвано исключение IOError. {}'.format(e.args[-1]))
В примере выше мы перехватываем только исключение IOError
. Многие новички не
знают, что мы можем обрабатывать несколько исключений.
Мы можем использовать три метода обработки множества исключений. Первый заключается в создании кортежа из всех возможных исключений. Что-то подобное:
try:
file = open('test.txt', 'rb')
except (IOError, EOFError) as e:
print("Было вызвано исключение. {}".format(e.args[-1]))
Другой методы заключается в обработке каждого исключения в отдельном блоке
except
. Мы можем иметь неограниченное их число (но не менее одного).
Очередной пример:
try:
file = open('test.txt', 'rb')
except EOFError as e:
print("Было вызвано исключение EOFError.")
raise e
except IOError as e:
print("Было вызвано исключение IOError.")
raise e
Таким образом, если исключение не перехватывается первым блоком except
, то
оно может быть обработано следующим, или не быть обработанным вовсе.
Последний метод заключается в перехвате ВСЕХ исключений:
try:
file = open('test.txt', 'rb')
except Exception:
# Логирование, если оно вам требуется
raise
Это может быть полезно, когда вы не знаете какие исключения могут возникнуть в вашей программе.
Основной код помещается в блок try
. Дальше идут блоки except
, которые
исполняются, если в блоке try
было вызвано определённое исключение. Третьим
типом блоков, следующим за двумя первыми, может быть finally
. Код в блоке
finally
будет исполнен вне зависимости от того, вызвал ли код в блоке
try
исключение или нет. Это может быть полезно для финальной "чистки"
после работы основного скрипта. Вот простой пример:
try:
file = open('test.txt', 'rb')
except IOError as e:
print('Было вызвано исключение IOError. {}'.format(e.args[-1]))
finally:
print("Я буду напечатан вне зависимости от исключений в блоке try!")
# Вывод: Было вызвано исключение IOError. No such file or directory
# Я буду напечатан вне зависимости от исключений в блоке try!
Иногда мы можем захотеть исполнить определенный код, если исключения
не было. Это легко сделать с помощью блока else
. Вы можете
спросить: почему нам нужен else
, если мы можем поместить этот код в блок
try
? Проблема в том, что исключение в этом коде, может быть в свою очередь
поймано try
, а мы можем этого и не хотеть. В целом, else
нечасто
используется, и я, честно говоря, редко к нему прибегаю сам. Пример:
try:
print('Я уверен, исключений не будет!')
except Exception:
print('Исключение')
else:
# Любой код, который должен быть исполнен, если исключение в блоке
# try не было вызвано, но для которого не должна проводиться
# обработка исключений
print('Я буду исполнен, если в try не будет исключений.'
'Мои исключения не будут обрабатываться.')
finally:
print('Я буду исполнен в любом случае!')
# Вывод: Я уверен, исключений не будет!
# Я буду исполнен, если в try не будет исключений. Мои исключения не будут обрабатываться.
# Я буду исполнен в любом случае!
Блок else
, таким образом, исполняется при отсутствии исключений в блоке
try
. else
исполняется перед finally
.