Найти в Дзене
КУЗИНОБИТ

Урок 15: Обработка ошибок и исключения в Python.

Добро пожаловать на пятнадцатый урок нашего курса по программированию на Python! Ранее мы изучили различные структуры данных, циклы и другие аспекты языка. Сегодняшняя тема — исключения и обработка ошибок. Знание того, как корректно обращаться с непредвиденными ситуациями, сделает ваши программы более надёжными, удобными для сопровождения и понятными другим разработчикам. В данную статью добавлены ссылки на GitHub в каждом примере. Также общая ссылка на GitHub для данного урока: Во время выполнения программы могут возникать различные сбои или ошибки (например, деление на ноль, отсутствие файла, неверный тип данных). Если подобная ошибка не будет правильно обработана, программа завершится аварийно и выведет сообщение об ошибке. Чтобы предотвратить такие ситуации и дать возможность программе корректно отреагировать на проблему, в Python существует механизм исключений. Чтобы перехватить и обработать возникшую ошибку (исключение), используется блок try-except: try:
# Код, в котором воз
Оглавление

Добро пожаловать на пятнадцатый урок нашего курса по программированию на Python! Ранее мы изучили различные структуры данных, циклы и другие аспекты языка. Сегодняшняя тема — исключения и обработка ошибок. Знание того, как корректно обращаться с непредвиденными ситуациями, сделает ваши программы более надёжными, удобными для сопровождения и понятными другим разработчикам.

В данную статью добавлены ссылки на GitHub в каждом примере. Также общая ссылка на GitHub для данного урока:
python_course/lesson_15 at main · kuzinobit/python_course

Зачем нужна обработка исключений?

Во время выполнения программы могут возникать различные сбои или ошибки (например, деление на ноль, отсутствие файла, неверный тип данных). Если подобная ошибка не будет правильно обработана, программа завершится аварийно и выведет сообщение об ошибке. Чтобы предотвратить такие ситуации и дать возможность программе корректно отреагировать на проблему, в Python существует механизм исключений.

Примеры, когда возникают ошибки:

  1. Деление числа на ноль.
  2. Обращение к индексу списка, которого не существует.
  3. Использование неправильного типа данных в математических операциях.
  4. Ошибка ввода-вывода при работе с файлами.

Ключевые конструкции.

Блок try-except.

Чтобы перехватить и обработать возникшую ошибку (исключение), используется блок try-except:

python_course/lesson_15/try_except.py at main · kuzinobit/python_course
Пример использования try-except.
Пример использования try-except.
try:
# Код, в котором возможна ошибка
result = 10 / 0
except ZeroDivisionError:
# Обработка ошибки
print("Деление на ноль невозможно!")

try: Внутри этого блока пишется код, который потенциально может вызывать ошибку.

except: Если в блоке try возникло указанное исключение, выполнение переходит в блок except. Если ошибка не произошла, блок except пропускается.

Несколько обработчиков исключений.

Можно указывать несколько блоков except, чтобы обрабатывать разные ошибки по-разному:

python_course/lesson_15/many_except.py at main · kuzinobit/python_course
Пример except 1.
Пример except 1.
Пример except 2.
Пример except 2.
try:
value = int(input("Введите число: "))
result = 100 / value
print(result)
except ValueError:
print("Ошибка: вы ввели не число!")
except ZeroDivisionError:
print("Ошибка: деление на ноль недопустимо!")

Блок else.

Если в блоке try не произошло ошибок, то код в блоке else будет выполнен. Таким образом, можно отделить логику успешного выполнения от кода обработки ошибок:

python_course/lesson_15/try_else.py at main · kuzinobit/python_course
Пример использования else.
Пример использования else.
try:
file = open("data.txt", "r")
except FileNotFoundError:
print("Файл не найден.")
else:
content = file.read()
print("Содержимое файла:", content)
file.close()

Блок finally.

Код в блоке finally всегда будет выполнен, даже если в блоке try возникла ошибка. Это удобно для освобождения системных ресурсов (закрытия файлов, сетевых соединений и т.д.):

python_course/lesson_15/try_finally.py at main · kuzinobit/python_course
Пример выполнения finally.
Пример выполнения finally.
try:
file = open("data.txt", "r")
# Работа с файлом
finally:
print("Этот блок кода выполнится даже при наличии ошибки")

Полная конструкция.

Вместе блоки try, except, else и finally обеспечивают гибкую обработку различных сценариев и отделяют удачный исход от неудачного:

python_course/lesson_15/try_full.py at main · kuzinobit/python_course
Пример полной конструкции try.
Пример полной конструкции try.
try:
file = open("data.txt", "r")
except FileNotFoundError:
print("Файл не найден.")
else:
data = file.read()
print("Файл прочитан успешно!")
file.close()
finally:
print("Блок finally: выполняется в любом случае.")

Генерация исключений: raise.

В отдельных ситуациях может понадобиться самостоятельно «выбросить» (сгенерировать) исключение, если обнаружена неверная ситуация. Для этого используется оператор raise:

python_course/lesson_15/try_raise.py at main · kuzinobit/python_course
Пример использования raise.
Пример использования raise.
def check_score(score):
if score < 0:
raise ValueError("Отрицательное число не может быть счётом!")
elif score > 100:
raise ValueError("Счёт не может превышать 100!")
else:
print("Счёт в норме:", score)

try:
check_score(-10)
except ValueError as e:
print(f"Ошибка: {e}")

Часто встречающиеся исключения.

Python содержит множество встроенных классов исключений, вот несколько часто используемых:

  • ValueError: Неверный тип или формат данных (например, при конвертации строки в число).
  • ZeroDivisionError: Деление на ноль.
  • IndexError: Использование индекса, выходящего за границы последовательности.
  • KeyError: Попытка доступа к отсутствующему ключу в словаре.
  • FileNotFoundError: Указанный файл не найден.
  • IOError: Ошибка ввода-вывода (чтение-запись).
  • NameError: Обращение к несуществующей переменной.

Полный список исключений вы найдёте в официальной документации Python.

Собственные классы исключений.

Иногда важно определить свои классы исключений, чтобы сообщать об особых ошибках, специфичных для конкретной задачи или библиотеки:

python_course/lesson_15/try_custom.py at main · kuzinobit/python_course
Пример использования кастомного исключения
Пример использования кастомного исключения
class MyCustomError(Exception):
"""Особое исключение для моей программы."""
pass

def process_value(x):
if x < 0:
raise MyCustomError("Значение не может быть отрицательным!")
return x * 2
try:
result = process_value(-5)
except MyCustomError as e:
print(f"Произошла ошибка: {e}")

Практические примеры.

Пример 1. Безопасное чтение файла:

python_course/lesson_15/example_1_try.py at main · kuzinobit/python_course
Пример безопасного чтения файла.
Пример безопасного чтения файла.
def read_file(file_name):
try:
with open(file_name, 'r') as f:
return f.read()
except FileNotFoundError:
print("Файл не найден.")
except PermissionError:
print("Недостаточно прав для чтения файла.")

content = read_file("data.txt")
if content is not None:
print("Содержимое файла:", content)

Пример 2. Обработка нескольких ошибок при вводе данных:

python_course/lesson_15/example_2_try.py at main · kuzinobit/python_course
Пример первого условия.
Пример первого условия.
Пример второго условия.
Пример второго условия.
def safe_division():
try:
a = float(input("Введите число a: "))
b = float(input("Введите число b: "))
return a / b
except ValueError:
print("Ошибка ввода: нужно ввести число.")
except ZeroDivisionError:
print("Деление на ноль недопустимо.")

result = safe_division()
if result is not None:
print("Результат:", result)

Пример 3. Пользовательское исключение при неверном пароле:

python_course/lesson_15/example_3_try.py at main · kuzinobit/python_course
Пример кастомного исключения при использовании неверного пароля
Пример кастомного исключения при использовании неверного пароля
class InvalidPasswordError(Exception):
pass
def login(password):
if password != "secret":
raise InvalidPasswordError("Неверный пароль!")
print("Успешный вход в систему")

try:
login("wrong")
except InvalidPasswordError as e:
print(f"Ошибка: {e}")

Рекомендации и лучшие практики.

  1. Используйте конкретные исключения: если известно, какие ошибки могут произойти, перехватывайте именно их.
  2. Не злоупотребляйте перехватом всех ошибок (except Exception:), так как это может скрыть критические сбои.
  3. Проверяйте условия заранее: иногда проще проверить условие (if b != 0:) до операции, чем перехватывать ошибку.
  4. Ограничивайте зону try: старайтесь делать блок try как можно меньше, чтобы понимать, какая именно операция вызвала исключение.
  5. Используйте finally или конструкцию with ... as ... для гарантированного освобождения ресурсов.

Заключение пятнадцатого урока.

Сегодня мы:

  • Рассмотрели механизм исключений в Python и поняли, как они помогают в обработке ошибок.
  • Изучили основные блоки try, except, else, finally и их роль.
  • Узнали, как самостоятельно генерировать ошибки с помощью raise.
  • Научились определять собственные исключения для более точной диагностики проблем.
  • Познакомились с лучшими практиками в области обработки ошибок.

Правильная работа с исключениями — важный шаг к созданию устойчивых и надёжных программ. В результате ваш код становится более понятным, так как явно отражает все возможные «нештатные» сценарии.

Домашняя работа.

Задание 1. Функция safe_divide.

  1. Напишите функцию safe_divide(a, b), которая возвращает результат деления a / b.
  2. Если деление на ноль невозможно, обработайте ошибку и верните None.
  3. Проверьте в коде, что функция действительно возвращает None при делении на ноль.

Задание 2. Чтение и анализ файла.

  1. Напишите программу, которая запрашивает у пользователя путь к файлу.
  2. Если файла не существует, сообщите об этом. Если существует — прочитайте построчно и выведите на экран только строки, содержащие слово "Python".
  3. Обработайте возможные ошибки (например, проблемы с доступом к файлу).

Задание 3*. Своя ошибка.

  1. Создайте класс ошибки NegativeNumberError, унаследованный от Exception.
  2. Напишите функцию factorial(n), вычисляющую факториал n. Если n отрицательное, сгенерируйте NegativeNumberError.
  3. Оформите вызов в блоке try-except, отловите NegativeNumberError и отобразите сообщение «Факториал отрицательного числа не определён».

Вопросы для самопроверки.

  1. В чём преимущество использования механизма исключений по сравнению с возвращением кодов ошибок?
  2. Как работает блок else в связке с try и except?
  3. Какая роль у блока finally, и в каких случаях его использование критически важно?
  4. Как сгенерировать исключение самостоятельно и зачем это может быть нужно?
  5. Почему в некоторых случаях нужно определять собственный класс ошибок?

Свои домашние работы отправляйте на почтовый ящик homework@kuzinobit.com.

Поздравляю с успешным освоением обновлённого пятнадцатого урока! На следующем уроке мы рассмотрим работу с файлами в Python, где вы научитесь открывать, читать и записывать данные, а также правильно управлять ресурсами. Это откроет дорогу к созданию более сложных и практичных программ.

Друзья, ставьте лайки, пишите комментарии и подписывайтесь на канал — впереди нас ждёт ещё много интересного! До новых встреч!