Введение
В этом практическом занятии (лабораторной работе) вы научитесь проверять, было ли поймано исключение в Python с использованием различных методов. Лабораторная работа сосредоточена на обработке исключений, которая является важной частью написания надежного и устойчивого к ошибкам кода на Python.
В рамках лабораторной работы вы узнаете, как работает процесс обработки исключений с использованием блоков try...except для элегантной обработки ошибок, таких как ZeroDivisionError. Вы научитесь устанавливать флаг внутри блока except, чтобы указать, что исключение было поймано. Наконец, в лабораторной работе будет представлено понятие использования менеджеров контекста для более контролируемой обработки исключений.
Изучить процесс обработки исключений
На этом этапе вы узнаете о обработке исключений в Python. Обработка исключений является важной частью написания надежного и устойчивого к ошибкам кода. Она позволяет вам элегантно обрабатывать ошибки, которые могут возникнуть во время выполнения программы, предотвращая ее аварийное завершение и обеспечивая более удобный для пользователя опыт.
Начнем с простого примера. Предположим, вы хотите разделить два числа, но второе число может быть равно нулю. Деление на ноль является неопределенной операцией и вызовет исключение ZeroDivisionError в Python.
Откройте редактор VS Code в среде LabEx.
Создайте новый файл с именем
division.pyв каталоге~/project.touch ~/project/division.pyОтредактируйте файл
division.pyи добавьте следующий код:## division.py numerator = 10 denominator = 0 result = numerator / denominator print(result)Запустите скрипт с помощью команды
python:python ~/project/division.py
Вы увидите сообщение об ошибке, похожее на следующее:
Traceback (most recent call last):
File "/home/labex/project/division.py", line 4, in <module>
result = numerator / denominator
ZeroDivisionError: division by zero
Это сообщение об ошибке указывает, что произошло исключение ZeroDivisionError, так как мы попытались разделить на ноль. Без обработки исключений программа завершается аварийно.
Теперь используем обработку исключений для элегантной обработки этой ошибки.
Измените файл
division.py, добавив блокtry...except:## division.py numerator = 10 denominator = 0 try: result = numerator / denominator print(result) except ZeroDivisionError: print("Error: Cannot divide by zero.")
В этом коде блок try содержит код, который может вызвать исключение. Если в блоке try возникает исключение ZeroDivisionError, будет выполнен код в блоке except.
Запустите скрипт еще раз:
python ~/project/division.py
Теперь вместо аварийного завершения программа выведет:
Error: Cannot divide by zero.
Это демонстрирует базовую структуру обработки исключений:
- Блок
tryзаключает в себе код, который может вызвать исключение. - Блок
exceptуказывает тип исключения, которое нужно поймать, и код, который будет выполнен, если это исключение возникнет.
Вы также можете ловить несколько типов исключений с помощью нескольких блоков except:
## division.py
numerator = 10
denominator = "abc"
try:
result = numerator / int(denominator)
print(result)
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
except ValueError:
print("Error: Invalid input. Please enter a number.")
В этом примере мы добавили обработчик исключения ValueError. Если denominator не может быть преобразован в целое число (например, если это строка, такая как "abc"), будет вызвано исключение ValueError, и будет выполнен соответствующий блок except.
Запустите скрипт:
python ~/project/division.py
Вывод:
Error: Invalid input. Please enter a number.
Обработка исключений позволяет вам писать более надежные и удобные для пользователя программы, предвидя и обрабатывая потенциальные ошибки.
Установить флаг в блоке except
На этом этапе вы научитесь использовать флаг внутри блока except для управления потоком выполнения программы в зависимости от того, произошло ли исключение или нет. Это полезный прием, когда вам нужно выполнять разные действия в зависимости от результата выполнения блока try.
Построим на предыдущем примере. Предположим, вы хотите вычислить обратное число, но только в том случае, если деление прошло успешно. Вы можете использовать флаг, чтобы указать, было ли деление успешным, и затем вычислить обратное число соответственно.
Откройте редактор VS Code в среде LabEx.
Измените файл
division.pyв каталоге~/project, добавив флаг:## division.py numerator = 10 denominator = 2 success = True ## Initialize the flag to True try: result = numerator / denominator print("Result of division:", result) except ZeroDivisionError: print("Error: Cannot divide by zero.") success = False ## Set the flag to False if an error occurs except ValueError: print("Error: Invalid input. Please enter a number.") success = False ## Set the flag to False if an error occurs else: print("No exception occurred.") if success: try: reciprocal = 1 / result print("Reciprocal:", reciprocal) except ZeroDivisionError: print("Cannot calculate reciprocal of zero.") else: print("Reciprocal calculation skipped due to error.")В этом коде:
- Мы инициализируем флаг с именем
successсо значениемTrueперед блокомtry. - Если возникает исключение
ZeroDivisionErrorилиValueError, мы устанавливаем флагsuccessв значениеFalseвнутри соответствующего блокаexcept. - После блока
try...exceptмы проверяем значение флагаsuccess. Если оно по-прежнему равноTrue, это означает, что исключение не произошло, и мы можем безопасно вычислить обратное число. В противном случае мы пропускаем вычисление обратного числа. - Мы также добавили блок
else, который будет выполнен, если в блокеtryне произошло никаких исключений.
- Мы инициализируем флаг с именем
Запустите скрипт с допустимым значением знаменателя:
python ~/project/division.pyВывод:
Result of division: 5.0 No exception occurred. Reciprocal: 0.2Теперь измените значение
denominatorна0и запустите скрипт снова:## division.py numerator = 10 denominator = 0 ## Change the denominator to 0 success = True try: result = numerator / denominator print("Result of division:", result) except ZeroDivisionError: print("Error: Cannot divide by zero.") success = False except ValueError: print("Error: Invalid input. Please enter a number.") success = False else: print("No exception occurred.") if success: try: reciprocal = 1 / result print("Reciprocal:", reciprocal) except ZeroDivisionError: print("Cannot calculate reciprocal of zero.") else: print("Reciprocal calculation skipped due to error.")Запустите скрипт:
python ~/project/division.pyВывод:
Error: Cannot divide by zero. Reciprocal calculation skipped due to error.
Это демонстрирует, как можно использовать флаг в блоке except для управления потоком выполнения программы и выполнения разных действий в зависимости от того, произошло ли исключение или нет.
Использовать менеджеры контекста для управления
На этом этапе вы научитесь использовать менеджеры контекста в Python для упрощения обработки исключений и обеспечения правильного управления ресурсами, даже если возникают исключения. Менеджеры контекста особенно полезны при работе с файлами, сетевыми соединениями и другими ресурсами, которые необходимо явно закрывать или освобождать.
Менеджер контекста - это объект, который определяет методы __enter__ и __exit__. Оператор with используется для выполнения блока кода в контексте менеджера контекста. Метод __enter__ вызывается при входе в блок with, а метод __exit__ - при выходе из блока with, независимо от того, произошло ли исключение.
Начнем с простого примера чтения файла с использованием менеджера контекста.
Откройте редактор VS Code в среде LabEx.
Создайте новый файл с именем
file_handling.pyв каталоге~/project.touch ~/project/file_handling.pyОтредактируйте файл
file_handling.pyи добавьте следующий код:## file_handling.py filename = "my_file.txt" try: with open(filename, "w") as f: f.write("Hello, LabEx!\n") f.write("This is a test file.\n") except IOError as e: print(f"An I/O error occurred: {e}") try: with open(filename, "r") as f: content = f.read() print("File content:") print(content) except FileNotFoundError: print(f"The file '{filename}' was not found.") except IOError as e: print(f"An I/O error occurred: {e}")В этом коде:
- Мы используем оператор
with open(filename, "w") as f:, чтобы открыть файлmy_file.txtв режиме записи ("w"). Функцияopen()возвращает объект файла, который присваивается переменнойf. - Оператор
withгарантирует, что файл автоматически закроется при выходе из блока, даже если возникнет исключение. - Мы записываем две строки текста в файл с помощью метода
f.write(). - Затем мы используем оператор
with open(filename, "r") as f:, чтобы открыть тот же файл в режиме чтения ("r"). - Мы читаем весь контент файла с помощью метода
f.read()и выводим его в консоль. - Мы оборачиваем операции с файлом в блоки
try...except, чтобы обработать потенциальные исключенияFileNotFoundErrorиIOError.
- Мы используем оператор
Запустите скрипт:
python ~/project/file_handling.pyВывод:
File content: Hello, LabEx! This is a test file.Если файл
my_file.txtне существует, скрипт создаст его и запишет указанный контент. Если файл уже существует, его содержимое будет перезаписано. Операторwithгарантирует, что файл будет правильно закрыт в любом случае.
Рассмотрим другой пример, где исключение может возникнуть во время обработки файла:
## file_handling.py
filename = "my_file.txt"
try:
with open(filename, "r") as f:
for line in f:
## Simulate an error during processing
if "test" in line:
raise ValueError("Simulated error during processing")
print("Line:", line.strip())
except FileNotFoundError:
print(f"The file '{filename}' was not found.")
except ValueError as e:
print(f"A value error occurred: {e}")
except IOError as e:
print(f"An I/O error occurred: {e}")
В этом примере мы имитируем ошибку, вызывая исключение ValueError, если строка содержит слово "test". Даже если эта ошибка произойдет, оператор with гарантирует, что файл будет правильно закрыт.
Запустите скрипт:
python ~/project/file_handling.py
Вывод:
Line: Hello, LabEx!
A value error occurred: Simulated error during processing
Менеджеры контекста предоставляют чистый и надежный способ управления ресурсами и обработки исключений в Python. Они гарантируют, что ресурсы будут правильно освобождены, даже если возникают ошибки, делая ваш код более надежным и легким в поддержке.
Резюме
В этом практическом занятии вы начали с изучения обработки исключений в Python, которая является важной техникой для написания надежного кода. Вы начали с простого примера деления, который вызывает исключение ZeroDivisionError при делении на ноль, в результате чего программа завершает работу. Затем вы реализовали блок try...except для элегантной обработки исключения ZeroDivisionError, предотвращая аварийное завершение программы и выводя вместо этого информативное сообщение об ошибке.



