try, except, else и finally

Тема дорожной карты · Python Programming

try/except конструкция в Python используется для обработки исключений, что позволяет программе реагировать на ошибки и продолжать выполнение. Важно использовать максимально узкое исключение, которое можно обработать, чтобы избежать скрытия реальных проблем. Например, использование except Exception или голого except: может скрыть баги и глушить исключения, такие как KeyboardInterrupt.

В try блоке следует оставлять только те строки кода, которые могут вызвать исключение. Ветка успеха, которая не вызывает исключений, должна быть помещена в else блок. Это позволяет избежать ненужного выполнения кода, который не требует обработки исключений. Обязательная очистка ресурсов, независимо от того, произошло ли исключение или нет, должна быть помещена в finally блок. Если это возможно, рекомендуется использовать контекстные менеджеры, такие как with конструкция, для автоматической очистки ресурсов.

Для сохранения полного трейса исключения, необходимо выбросить исключение повторно через голый raise. Это позволяет сохранить полную цепочку исключений, что может быть полезно для диагностики ошибок. В Python 3.11 и выше появился новый синтаксис except*, который позволяет ловить группы исключений, используя ExceptionGroup.

Как это работает

try/except/else/finally конструкция используется для обработки рантайм-ошибок, позволяя программе продолжать выполнение даже при возникновении исключений. Исключения в Python организованы в иерархию, где BaseException является базовым классом для всех исключений, включая Exception, который является базовым классом для всех стандартных исключений, таких как ValueError, TypeError, KeyError, IOError и так далее.

Пользовательские исключения наследуются от класса Exception и могут иметь дополнительные атрибуты, которые могут быть полезны для диагностики ошибок. raise ключевое слово используется для выброса исключения, которое затем может быть обработано в блоке except. raise ... from cause позволяет сохранить цепочку исключений, что может быть полезно для диагностики ошибок.

Контекстные менеджеры, такие как with конструкция, гарантируют автоматическую очистку ресурсов, даже если исключение было выброшено. Это особенно полезно для работы с ресурсами, такими как файлы или блокировки, которые должны быть освобождены, независимо от того, произошло ли исключение или нет. Модуль logging является стандартом для записи ошибок с временными метками, уровнями и обработчиками.

Когда применять

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

Исключения должны использоваться только для обработки исключительных условий, а не для управления потоком выполнения программы. Например, проверка наличия ключа в словаре с помощью if key in d является более предпочтительным способом, чем попытка доступа к ключу в словаре с помощью try: d[key] except KeyError. Пользовательские исключения могут быть полезны для того, чтобы вызывающий код мог отличить ошибки, вызванные вашим кодом, от общих ошибок.

Типичные ошибки

Типичные ошибки при использовании try/except/else/finally конструкции включают тихое съедание исключений с помощью except: pass, что может скрыть реальные проблемы. Также ошибкой является ловля исключения Exception на верхнем уровне функции и re-raise без контекста, что может привести к потере информации о происхождении исключения. Использование assert для рантайм-проверок также является ошибкой, так как это может быть удалено с помощью ключа -O в командной строке Python.

Связанные понятия

Полезные ресурсы

Проверить знания (1)

Загрузка вопросов…