Обработка исключений в Python: try, except, else и finally подробно
Обработка исключений в Python: try, except, else и finally
Это руководство проводит вас через конструкции обработки исключений Python с практическими примерами кода и советами по лучшим практикам.
Видео: Обработка исключений в Python (try..except..finally)
Исключения в Python
Python возбуждает встроенные исключения при каждой ошибке времени выполнения. Интерпретатор останавливает текущий блок кода и распространяет исключение вверх по стеку вызовов, пока не найдёт обработчик. Если обработчика нет, программа завершается аварийно и печатает трассировку.
Рассмотрим цепочку вызовов: A вызывает B, который вызывает C. Если C возбуждает исключение, не обработанное локально, оно всплывает к B, затем к A. Необработанные исключения приводят к внезапному крашу программы.
Перехват исключений в Python
Для перехвата исключения поместите потенциально небезопасный код внутрь блока try. Клауза except содержит логику, выполняемую при возникновении исключения.
Вот краткий пример, демонстрирующий поток:
# Импорт модуля sys для инспекции типа исключения
import sys
random_list = ['a', 0, 2]
for entry in random_list:
try:
print("The entry is", entry)
r = 1 / int(entry)
break
except:
print("Oops!", sys.exc_info()[0], "occurred.")
print("Next entry.")
print()
print("The reciprocal of", entry, "is", r)
Вывод
The entry is a Oops! <class 'ValueError'> occurred. Next entry. The entry is 0 Oops! <class 'ZeroDivisionError'> occurred. Next entry. The entry is 2 The reciprocal of 2 is 0.5
Код перебирает random_list. Если преобразование в int или деление неудачно, блок except обрабатывает ошибку, логирует её и переходит к следующему элементу. При успешном преобразовании цикл прерывается и выводится обратное значение.
Так как все встроенные исключения наследуются от Exception, их можно перехватывать общим способом:
# Импорт модуля sys для инспекции типа исключения
import sys
random_list = ['a', 0, 2]
for entry in random_list:
try:
print("The entry is", entry)
r = 1 / int(entry)
break
except Exception as e:
print("Oops!", e.__class__, "occurred.")
print("Next entry.")
print()
print("The reciprocal of", entry, "is", r)
Вывод идентичен, но обработчик теперь ссылается на конкретный класс исключения через e.__class__.
Перехват конкретных исключений в Python
Широкая перехват всех исключений может маскировать баги и затруднять отладку. Вместо этого перечисляйте только ожидаемые типы исключений.
Блок try может содержать несколько клауз except; выполняется только первый подходящий. Пример:
try:
# код, который может вызвать ошибку
pass
except ValueError:
# обработать ValueError
pass
except (TypeError, ZeroDivisionError):
# обработать либо TypeError, либо ZeroDivisionError
pass
except Exception:
# запасной вариант для любого другого исключения
pass
Возбуждение исключений в Python
Помимо автоматических исключений, разработчики могут возбуждать ошибки явно с помощью оператора raise. Опционально можно передать сообщение для уточнения причины.
raise KeyboardInterrupt
# Traceback: KeyboardInterrupt
raise MemoryError("This is an argument")
# Traceback: MemoryError: This is an argument
try:
a = int(input("Enter a positive integer: "))
if a <= 0:
raise ValueError("That is not a positive number!")
except ValueError as ve:
print(ve)
Клауза else в try Python
Опциональная клауза else выполняется только тогда, когда блок try завершается без возбуждения исключения. Этот паттерн разделяет код успешного пути от обработки ошибок.
Пример: вывод обратного значения чётного числа.
# программа для вывода обратного значения чётных чисел
try:
num = int(input("Enter a number: "))
assert num % 2 == 0
except:
print("Not an even number!")
else:
reciprocal = 1 / num
print(reciprocal)
Вывод при вводе нечётного числа:
Enter a number: 1 Not an even number!
Вывод при вводе чётного числа:
Enter a number: 4 0.25
Обратите внимание: если num равен нулю, ZeroDivisionError возбуждается в блоке else и не перехватывается предшествующей клаузой except.
Конструкция try…finally в Python
Клауза finally гарантирует, что код очистки выполнится независимо от того, произошло исключение или нет. Это критично при работе с внешними ресурсами: файлами, сетевыми соединениями или GUI.
Типичное использование с файлами:
try:
f = open("test.txt", encoding='utf-8')
# выполняем файловые операции
finally:
f.close()
Файл всегда закрывается, даже если возникает ошибка во время обработки.
Python
- Ключевые слова и идентификаторы в Python: мастерство зарезервированных слов и соглашений об именовании
- Операторы, отступы и комментарии в Python: понятное руководство
- Переменные, константы и литералы в Python — подробное руководство
- Мастерство преобразования типов в Python: Полное руководство
- Мастерство ввода-вывода и импорта модулей в Python: Практическое руководство
- Оператор pass в Python: практическое руководство
- Глобальные, локальные и nonlocal переменные в Python: понимание и применение
- Управление директориями и файлами в Python: полное руководство
- Обработка исключений в Python: try, except, else и finally подробно
- Создание удалённого датчика температуры на Raspberry Pi и Python — пошаговое руководство