Python
Python
Сегодня 🌞
11.0 Try и Except
1. Введение в исключения:
Понимание, что такое исключения и почему они важны.
Рассмотрение типов исключений, встроенных в Python (например, TypeError , ValueError ,
FileNotFoundError ).
2. Использование блока try-except:
Основы синтаксиса try и except .
Как использовать блок try для защиты от исключений.
Создание простых обработчиков исключений.
11.3 Finally
1. Блок finally:
Введение в блок finally и его назначение.
Чем он отличается от else после try-except
Как использовать finally для выполнения кода после завершения блока try-except , независимо от того,
было ли исключение.
2. Исключения в блоке finally:
Как обрабатывать исключения, возникающие в блоке finally .
Влияние исключений в finally на обработку исключений в более высоких уровнях.
3. Исключения в блоке try с finally :
Как взаимодействуют исключения, возникающие в блоках try и finally .
Порядок выполнения кода в случае исключения в try и finally .
11.4 Raise
1. Генерация исключений:
Использование оператора raise для явного создания исключения.
Как передавать информацию и контекст в исключение.
Работа с as from в исключениях
2. Создание собственных исключений:
Как определять пользовательские исключения с помощью классов.
Добавление дополнительной информации и методов в пользовательские исключения.
3. Исключения и наследование:
Как использовать наследование для создания иерархии пользовательских исключений.
Преимущества структурирования исключений с помощью наследования.
4. Контекст исключений:
Понимание контекста исключений и его роли в отладке.
Как связывать исключения с предыдущими и добавлять контекст.
try:
# код, который может вызвать исключение
except Название_исключения:
# код, который будет выполнен, если возникнет исключение
Очевидно, что при вызове этой функции с b равным нулю вернется исключение ZeroDivisionError . Чтобы
предотвратить ненадлежащую работу программы, можно использовать блок try-except :
try:
result = divide(10, 0)
except ZeroDivisionError:
print("Ошибка: деление на ноль!")
В этом случае, вместо завершения программы с ошибкой, мы получим сообщение: Ошибка: деление на ноль!
def user_divide():
try:
a = float(input("Введите делимое: "))
b = float(input("Введите делитель: "))
result = a / b
except ValueError:
print("Ошибка: некорректное значение. Попробуйте еще раз!")
return user_divide()
except ZeroDivisionError:
print("Ошибка: деление на ноль! Используйте другое значение делителя.")
return user_divide()
return result
print(user_divide())
Здесь при возникновении исключения ValueError или ZeroDivisionError функция user_divide вызывает сама себя,
позволяя пользователю повторить ввод данных.
Использование блоков try-except позволяет обрабатывать исключения и предотвращать аварийное завершение работы
программы, делая ее более устойчивой к ошибкам.
try:
# Code that may raise exceptions
pass
except FileNotFoundError:
# Handle FileNotFoundError
pass
except ZeroDivisionError:
# Handle ZeroDivisionError
pass
try:
# Code that may raise exceptions
pass
except FileNotFoundError as fne:
# Handle FileNotFoundError
print(f"File {fne.filename} not found.")
except ZeroDivisionError as zde:
# Handle ZeroDivisionError
print(f"Cannot divide by zero: {zde}")
В примере выше переменные fne и zde содержат конкретное исключение типа FileNotFoundError и
ZeroDivisionError , соответственно, и могут быть использованы для получения дополнительной информации об
ошибке.
try:
# Code that may raise exceptions
pass
except:
# Handle any exception
print("An unexpected error occurred.")
⚠️ Важно! Использование except без указания типа исключения широко критикуется, так как может приводить к
диагностированию неправильных ошибок и, как следствие, к багам в коде. Вместо этого, всегда старайтесь
обрабатывать конкретные типы исключений.
Тестирования кода: на начальных этапах разработки кода, когда мы пока не знаем, какие исключения могут
возникнуть.
Отладки: когда разрабатываем код, который потенциально может вызвать множество неизвестных исключений.
Обработка сторонних библиотек, в документации к которым отсутствует информация о возможных исключениях.
Однако, даже используя обработчик без типа, лучше включить также обработку конкретных исключений перед
использованием except без типа:
try:
# Code that may raise exceptions
pass
except FileNotFoundError:
# Handle FileNotFoundError
pass
except ZeroDivisionError:
# Handle ZeroDivisionError
pass
except:
print("An unknown error occurred.")
Таким образом, мы сможем справляться с разными типами ошибок, а также интерпретировать неспецифичные
исключения, когда другие обработчики не подходят.
try:
# код, который может вызвать исключение
except SomeException:
# код для обработки исключения
else:
# код для выполнения, если исключение не возникло
📚 Практические примеры
🌐 Элемент не найден в Selenium
try:
element = driver.find_element_by_css_selector('.element_class_name')
except NoSuchElementException:
print("Элемент не найден!")
else:
print("Найденный элемент:", element)
import json
try:
with open("data.json", "r") as f:
data = json.load(f)
except FileNotFoundError:
print("Файл data.json не найден!")
else:
print("Данные из файла JSON:", data)
Пример:
try:
# код, который может вызвать исключение №1
try:
# код, который может вызвать исключение №2
except SomeException2:
# код для обработки исключения №2
# дополнительный код после вложенного блока try-except,
# который должен быть выполнен, даже если возникло исключение №2
except SomeException1:
# код для обработки исключения №1
try:
# код, который может вызвать исключение FileNotFoundError
with open("example.txt", "r") as f:
try:
# код, который может вызвать исключение ValueError
num = int(f.readline())
except ValueError:
print("Не удалось прочитать число из файла!")
# дополнительный код, который должен быть выполнен,
# даже если возникло исключение ValueError
print("Чтение из файла завершено.")
except FileNotFoundError:
print("Файл example.txt не найден!")
Если файл example.txt не найден, будет выведено сообщение "Файл example.txt не найден!". Если файл найден, но
первая строка не может быть преобразована в число, будет выведено сообщение "Не удалось прочитать число из
файла!". В любом случае после обработки исключений (если они были) будет выведено сообщение "Чтение из файла
завершено."
11.3 Finally 🏁
1. Блок finally: 📦
Введение в блок finally и его назначение 🎯
Блок finally используется для задания операторов, которые должны быть выполнены в любом случае, независимо от
того, возникло ли исключение в блоке try . Это может быть полезно для очистки ресурсов или закрытия файлов после
завершения работы с ними.
Как использовать finally для выполнения кода после завершения блока try-except ,
независимо от того, было ли исключение 🛠️
Применение блока finally выглядит следующим образом:
try:
print("Try block")
# Здесь можно выполнять операции, которые могут вызвать исключение
except Exception as e:
print(f"Exception caught: {e}")
finally:
print("Finally block")
В этом примере, строка print("Finally block") выполнится независимо от того, возникло исключение в блоке try
или нет.
try:
print("Try block")
except Exception as e:
print(f"Exception caught: {e}")
finally:
try:
print("Finally block")
# Здесь может возникнуть еще одно исключение
except Exception as e:
print(f"Exception in finally block: {e}")
Этот пример позволяет обрабатывать исключения как в блоке try , так и в блоке finally , сохраняя информацию об
обоих исключениях.
11.4 Raise 🚀
1. Генерация исключений 💥
1.1 Использование оператора raise для явного создания исключения
В Python, raise используется для явной генерации исключений. Исключения могут возникать автоматически в
результате ошибок, но иногда полезно сгенерировать исключение в определенной точке кода с помощью оператора
raise .
def foo(x):
if x < 0:
raise ValueError("x должен быть положительным числом")
return x * 2
print(foo(-3))
В примере выше, функция foo вызывает исключение ValueError с помощью оператора raise , если аргумент x
меньше 0.
def foo(x):
if x < 0:
raise ValueError(f"x должен быть положительным числом, а x={x}")
return x * 2
print(foo(-3))
В этом примере, мы передаем информацию об ошибке (значение x ) в сообщении исключения, что помогает определить
причину ошибки и исправить её.
try:
x = int("five")
except ValueError as e:
raise TypeError("x должен быть числом") from e
Таким образом, мы можем сохранить исходное исключение ( ValueError , возникшее при конвертации строки "five" в
число) как контекст нового исключения ( TypeError ). Это упрощает отладку последующих проблем и сохраняет
сведения о первоначальной ошибке.
2. Создание собственных исключений 🛠️ (продвинутый уровень ⭐)
2.1 Как определять пользовательские исключения с помощью классов
Чтобы создать собственное исключение, мы должны определить новый класс, который наследует от базового класса
BaseException или одного из его подклассов.
class MyException(Exception):
pass
def foo():
raise MyException("Это мое исключение")
try:
foo()
except MyException as e:
print(f"Поймали мое исключение: {e}")
class MyException(Exception):
def __init__(self, message, code):
super().__init__(message)
self.code = code
def get_code(self):
return self.code
def foo():
raise MyException("Это мое исключение", 42)
try:
foo()
except MyException as e:
print(f"Поймали мое исключение: {e}. Код ошибки: {e.get_code()}")
3. Исключения и наследование 🌳
3.1 Как использовать наследование для создания иерархии пользовательских
исключений
Используя наследование, мы можем создать иерархию пользовательских исключений, разделяя их по категориям и
уровням абстракции.
class MyExceptionBase(Exception):
pass
class MySpecificException1(MyExceptionBase):
pass
class MySpecificException2(MyExceptionBase):
pass
На практике это упрощает обработку ошибок, позволяя легко разделить обработку разных типов исключений.
try:
x = int("five")
except ValueError as e:
raise TypeError("x должен быть числом") from e
В этом примере мы связываем новое исключение TypeError с предыдущим ValueError . Это позволяет сохранить
контекст обоих исключений и использовать его в процессе отладки.