В процессе работы программы могут возникать различные ошибки, которые вызывают *исключения*. Исключения останавливают выполнение программы, если их не обработать. Но Python предоставляет мощный механизм для обработки этих ситуаций — блоки try, except, else, и finally. В этой статье мы разберёмся, как грамотно обрабатывать ошибки и даже создавать свои собственные исключения.
Зачем нужна обработка исключений?
Обработка исключений позволяет нам избежать неожиданного завершения программы и предоставить пользователю понятные сообщения об ошибках. Например, программа может попытаться разделить число на ноль, что вызовет исключение ZeroDivisionError. Если такие случаи не предусмотреть, программа просто завершится с ошибкой. Но с помощью обработки исключений можно перехватить ошибку и сообщить об этом пользователю.
Обработка исключений с помощью try, except и finally
Базовая конструкция try-except
Для обработки исключений в Python используется конструкция try-except. В блоке try размещается код, который может вызвать ошибку. Если ошибка возникает, управление передаётся в блок except.
Пример:
try:
x = int(input("Введите число: "))
y = int(input("Введите ещё одно число: "))
result = x / y
print(f"Результат: {result}")
except ZeroDivisionError:
print("Ошибка: деление на ноль!")
except ValueError:
print("Ошибка: неверный ввод, нужно ввести число.")
Здесь обрабатываются два типа исключений:
- ZeroDivisionError — возникает при делении на ноль.
- ValueError — возникает, если введённые данные не могут быть преобразованы в число.
Блок else
Блок else используется, если в блоке try не произошло ошибок. Это полезно, когда нужно выполнить дополнительный код, если ошибок не было.
Пример:
try:
x = int(input("Введите число: "))
y = int(input("Введите ещё одно число: "))
result = x / y
except ZeroDivisionError:
print("Ошибка: деление на ноль!")
except ValueError:
print("Ошибка: неверный ввод.")
else:
print(f"Результат: {result}")
В этом случае блок else выполнится только если не возникнет ни одной ошибки.
📢 Подпишитесь на наш Telegram-канал Code Lab.
Там вы найдете анонсы обучающих статей и видео, готовый код для ваших проектов и увлекательные курсы. Ничего лишнего — только практика, вдохновение и развитие.
Блок finally
Блок finally выполняется всегда, независимо от того, произошло исключение или нет. Это полезно для освобождения ресурсов, закрытия файлов или других завершающих действий.
Пример:
try:
x = int(input("Введите число: "))
y = int(input("Введите ещё одно число: "))
result = x / y
print(f"Результат: {result}")
except ZeroDivisionError:
print("Ошибка: деление на ноль!")
except ValueError:
print("Ошибка: неверный ввод.")
finally:
print("Программа завершена.")
Блок finally всегда выполняется, даже если в процессе выполнения произошла ошибка.
Создание собственных исключений
Иногда стандартных исключений недостаточно, особенно когда мы хотим обработать специфические ошибки, связанные с логикой программы. В таких случаях можно создавать собственные исключения, наследуя их от встроенного класса Exception.
Пример создания собственного исключения:
class NegativeNumberError(Exception):
pass
def check_positive(number):
if number < 0:
raise NegativeNumberError("Число не должно быть отрицательным!")
try:
x = int(input("Введите положительное число: "))
check_positive(x)
except NegativeNumberError as e:
print(e)
except ValueError:
print("Ошибка: неверный ввод.")
В этом примере мы создаём своё исключение NegativeNumberError, которое вызывается, если число отрицательное.
Пример программы: Калькулятор с обработкой ошибок
Теперь создадим калькулятор, который обрабатывает следующие ошибки:
- Деление на ноль.
- Неверный ввод данных (например, если введены буквы вместо чисел).
class CalculatorError(Exception):
"""Базовый класс для других исключений"""
pass
class DivisionByZeroError(CalculatorError):
"""Исключение для деления на ноль"""
pass
class InvalidInputError(CalculatorError):
"""Исключение для неверного ввода данных"""
pass
def add(x, y):
return x + y
def subtract(x, y):
return x - y
def multiply(x, y):
return x * y
def divide(x, y):
if y == 0:
raise DivisionByZeroError("Нельзя делить на ноль!")
return x / y
def get_number(prompt):
try:
return float(input(prompt))
except ValueError:
raise InvalidInputError("Ошибка: введено не число!")
def main():
try:
num1 = get_number("Введите первое число: ")
num2 = get_number("Введите второе число: ")
operation = input("Введите операцию (+, -, *, /): ")
if operation == '+':
result = add(num1, num2)
elif operation == '-':
result = subtract(num1, num2)
elif operation == '*':
result = multiply(num1, num2)
elif operation == '/':
result = divide(num1, num2)
else:
raise InvalidInputError("Ошибка: неверная операция.")
print(f"Результат: {result}")
except CalculatorError as e:
print(e)
finally:
print("Калькулятор завершил работу.")
if __name__ == "__main__":
main()
Разбор программы:
- Определение пользовательских исключений: Мы создали два пользовательских исключения: DivisionByZeroError для деления на ноль и InvalidInputError для неправильного ввода.
- Функции для арифметических операций: Каждая арифметическая операция (сложение, вычитание, умножение и деление) оформлена как отдельная функция.
- Функция get_number(): Эта функция запрашивает ввод числа у пользователя и обрабатывает ошибку, если ввод не является числом, выбрасывая исключение InvalidInputError.
- Основная логика программы: Программа запрашивает два числа и операцию у пользователя. Если операция правильная, выполняется соответствующее арифметическое действие. Если ввод или операция некорректны, программа выводит сообщение об ошибке.
- Обработка ошибок: Все ошибки обрабатываются с использованием наших собственных исключений, что делает программу более гибкой и понятной.
Заключение
Обработка ошибок и исключений — важный аспект написания надёжных программ. Используя блоки try, except, finally, мы можем перехватывать ошибки и продолжать выполнение программы, избегая её неожиданного завершения. Кроме того, создание собственных исключений помогает лучше управлять логикой программы и предоставлять более точные сообщения об ошибках.
Комментарии
0