Представьте: вы пишете программу, а она вдруг «падает». 💥 Обидно, правда? Ошибки — часть жизни любого разработчика. Они возникают из-за опечаток, неверной логики или неожиданных событий, например, когда нужного файла просто нет.
Важно не только находить и исправлять ошибки, но и предвидеть их. Тогда ваша программа не рухнет при первом сбое, а сможет спокойно на него отреагировать.
Ошибки и исключения: в чем разница?
В Python ошибки делятся на два типа:
-
Синтаксические ошибки (SyntaxError). Это как грамматические ошибки в языке. Вы нарушили правила Python, и интерпретатор не понимает ваш код. Он останавливает выполнение еще до запуска.
# Пример синтаксической ошибки if True # Ожидается двоеточие после True print("Это ошибка")Такие ошибки легко найти: IDE или сам Python укажут на строку с проблемой.
-
Исключения (Exceptions). Эти ошибки возникают, когда программа уже запущена, даже если синтаксис идеален. Исключение — это событие, которое нарушает нормальный ход выполнения. Python генерирует его, когда сталкивается с чем-то, что не может обработать.
# Примеры исключений print(10 / 0) # ZeroDivisionError: деление на ноль my_list = [1, 2, 3] print(my_list[5]) # IndexError: индекс вне диапазона my_dict = {"name": "Alice"} print(my_dict["age"]) # KeyError: такого ключа нетЕсли исключение не обработать, программа аварийно завершится. Вы увидите сообщение об ошибке — трассировочный вывод или traceback. Он покажет тип исключения и место его возникновения.
Ловим ошибки: try-except
Чтобы программа не «падала» при исключениях, используйте конструкцию try-except. Она позволяет «поймать» ошибку и выполнить альтернативный код, вместо того чтобы завершать программу.
Синтаксис простой:
try:
# Код, который может вызвать исключение
# Если здесь возникает исключение, выполнение переходит в блок except
except ТипИсключения:
# Код, который выполняется, если возникло указанное исключение
Давайте разберем пример с делением на ноль:
try:
numerator = int(input("Введите числитель: "))
denominator = int(input("Введите знаменатель: "))
result = numerator / denominator
print(f"Результат деления: {result}")
except ZeroDivisionError:
print("Ошибка: Деление на ноль невозможно!")
except ValueError:
print("Ошибка: Введите только числа!")
print("Программа продолжает работу.")
Что здесь происходит?
- Блок
tryпытается выполнить операции ввода и деления. - Если пользователь введет
0в качестве знаменателя, возникнетZeroDivisionError. Управление перейдет в блокexcept ZeroDivisionError. - Если пользователь введет не число (например, текст), возникнет
ValueError. Управление перейдет в блокexcept ValueError. - Если ошибок нет, блоки
exceptпропускаются. - Сообщение "Программа продолжает работу." выведется в любом случае, потому что исключения обработаны.
Несколько except блоков
Вы можете использовать несколько except блоков для разных типов исключений. Python проверяет их по порядку сверху вниз и выполняет первый except блок, тип исключения которого совпадает с возникшим.
try:
num1 = int(input("Введите первое число: "))
num2 = int(input("Введите второе число: "))
res = num1 / num2
print(f"Результат: {res}")
except ValueError:
print("Вы ввели некорректные данные. Пожалуйста, введите числа.")
except ZeroDivisionError:
print("На ноль делить нельзя!")
except Exception as e: # Ловит любое другое исключение
print(f"Произошла непредвиденная ошибка: {e}")
Важно: Блок
except Exception as e:должен быть последним. Почему? Потому чтоException— это базовый класс для всех остальных исключений. Если вы поставите его раньше, он «поймает» все исключения, и более специфичныеexceptблоки никогда не будут достигнуты. Переменнаяeбудет содержать объект исключения, который часто дает полезную информацию об ошибке.
Блоки else и finally
Конструкцию try-except можно дополнить блоками else и finally:
-
else: Код в этом блоке выполняется, если в блокеtryне возникло никаких исключений.try: file_content = open("my_file.txt", "r").read() except FileNotFoundError: print("Файл не найден.") else: print("Файл успешно прочитан. Содержимое:") print(file_content) -
finally: Код в этом блоке выполняется всегда, независимо от того, возникло исключение или нет, и было ли оно обработано. Это идеальное место для очистки ресурсов (например, закрытия файлов или сетевых соединений).file = None try: file = open("data.txt", "r") content = file.read() print(content) except FileNotFoundError: print("Файл data.txt не найден.") finally: if file: # Проверяем, был ли файл открыт file.close() print("Файл закрыт.")
Практическое задание
Представьте, что вы пишете программу для расчета среднего балла студентов. Пользователь вводит оценки через запятую. Ваша задача — обработать возможные ошибки ввода.
- Запросите у пользователя строку с оценками (например, "5,4,3,5,2").
- Попробуйте преобразовать эту строку в список чисел.
- Рассчитайте средний балл.
- Используйте
try-exceptдля обработки следующих ситуаций:ValueError: Если пользователь ввел что-то, что нельзя преобразовать в число (например, "5,четыре,3").ZeroDivisionError: Если пользователь ввел пустую строку или только нечисловые значения, что приведет к пустому списку оценок и делению на ноль при расчете среднего.- Любое другое непредвиденное исключение.
- Выведите соответствующее сообщение об ошибке или средний балл.
# Ваш код здесь
# Примерная структура:
# try:
# grades_str = input("Введите оценки через запятую (например, 5,4,3): ")
# # ... ваш код для обработки и расчета ...
# except ValueError:
# # ...
# except ZeroDivisionError:
# # ...
# except Exception as e:
# # ...
Что дальше?
Теперь вы умеете обрабатывать стандартные исключения. Отлично! В следующем разделе мы пойдем дальше: научимся создавать собственные типы исключений. Это сделает ваш код еще понятнее и контролируемее, особенно в сложных проектах.