Как не обрабатывать исключения в Python
Я вижу, как многие люди неправильно обрабатывают исключения. Возможно, это относится и к вам. Следующая ситуация кажется вам знакомой?
Вы пишете какой-то код, но знаете, что используемая вами библиотека может вызвать исключение. Вы не помните, какой именно. На этом этапе заманчиво использовать так называемые универсальные блоки и заняться интересными вещами.
Содержание
Худший способ сделать это
Худшее, что вы можете сделать, это создать блок try-except, который перехватывает что угодно. Под общим я подразумеваю что-то вроде:
06
Такие блокирующие блоки плохи, потому что:
- Вы понятия не имеете, какие еще исключения могут быть вызваны (подробнее об этом позже).
- Мы скрываем исключение, автоматически используя пароль вместо регистрации ошибки в журнале.
Кроме того, пустое исключение будет содержать все, включая KeyboardInterrupt
. (control + c), SystemExit
и даже NameErrors
! Это означает, что следующий код не может быть остановлен корректно:
15пре>Не стесняйтесь попробовать. Вам нужно закрыть окно терминала или убить процесс Python, чтобы остановить эту программу.
Несколько лучший способ перехватывать все исключения
Напротив, при использовании
except Exception
, хотя по-прежнему быстрый и грязный способ перехватить слишком много исключений, по крайней мере, вы сможете правильно остановить запущенный процесс:23При перехвате
Exception
вы не поймаетеSystemExit
,KeyboardInterrupt
и другие подобные исключения. Почему так, спросите вы?Все исключения наследуются от класса с именем
BaseException
. . Согласно официальной документации:«Вtry
оператор сexcept
пункт, в котором упоминается конкретный класс, этот пункт также обрабатывает любые классы исключений, производные от этого класса». Пустойexcept
эквивалентноexcept BaseException
, поэтому он будет перехватывать все возможные исключения.Напротив, класс
Exception
определяется как:«Все встроенные исключения, не связанные с системой, являются производными от этого класса. Все пользовательские исключения также должны быть производными от этого класса».Бывает еще хуже
В следующем примере мы используем библиотеку os для получения текущего рабочего каталога. Однако мои жирные мизинцы сделали опечатку:
37Потому что
os.getcdw
не является функцией в модуле os, возникает ошибка NameError. Вместо того, чтобы терпеть неудачу, предложение exclude поймает ошибку, напечатает «ошибку», и программа продолжит работу, несмотря на нашу вопиющую опечатку. К сожалению, это не решается перехватомException
либо!Судя по всему, наша маленькая хитрость из первого шага не решает всех наших проблем. Итак, что должно мы делаем?
Поймай, с чем сможешь справиться
Фраза, которую часто можно услышать об исключениях:поймай то, что сможешь обработать. . Многие разработчики склонны работать с исключениями напрямую, хотя зачастую лучше позволить исключению распространиться на ту часть программы, которая может его обработать.
Например, рассмотрим часть текстового редактора, которая открывает и загружает файлы, назовем ее
OpenFile
учебный класс. Если пользователь запросил открыть несуществующий файл, вы можете либо напрямую обработать эту ошибку, либо позволить ей распространяться.В этом случае лучше передать исключение вызывающей стороне, потому что
OpenFile
понятия не имеет, насколько плохо это исключение для вызывающей стороны. Вызывающий может справиться с ситуацией несколькими способами:
- Вместо этого он может создать новый файл с таким именем и продолжить
- Возможно, вызывающему объекту нужно, чтобы файл был там, и в этом случае он может отобразить диалоговое окно с ошибкой, информирующее пользователя о том, что этот файл не существует.
В любом случае, это не выше OpenFile
класс, чтобы решить, что делать в случае FileNotFoundError
.
Так должно ли всегда распространяться исключение? Нет. Возможное исключение, которое можно обработать в классе FileOpen, — это TimeoutError
. Например, вы можете повторить попытку несколько раз, не беспокоя вызывающего абонента ошибкой. Это исключение, которое OpenFile
может справиться, поэтому можно перехватить его и повторить попытку.
Заключение
Вы ни при каких обстоятельствах не должны перехватывать больше исключений, чем можете обработать. Одеяло, кроме блоков, — это путь к ошибкам и непредсказуемому коду. Другими словами:ловите то, с чем можете справиться.
Если вы пишете свой код, имея в виду матру «поймай то, что сможешь обработать», написание универсальных блоков нарушает все правила. Так что, пожалуйста, прекрати это делать. В качестве упражнения вы можете вернуться к уже существующему коду и посмотреть, можно ли его улучшить с помощью новых знаний!
Python
- Операторы Python
- Ошибки Python и встроенные исключения
- Пользовательские исключения Python
- Как получить текущую дату и время в Python?
- Java перехватывает несколько исключений
- Как не отстать при обучении новому программному обеспечению
- Оператор Python Print():как печатать с примерами
- Добавление словаря Python:как добавить пару ключ/значение
- Новая строка Python:как печатать БЕЗ новой строки в Python
- Среднее значение Python:как найти СРЕДНЕЕ значение списка в Python