Как использовать try — except и не испортить себе жизнь
Разобрали на примерах, когда и как отлавливать ошибки с помощью блока и рассказали, когда эту конструкцию лучше не задействовать
2К открытий9К показов
Зачастую новичков в Python ошеломляет многочасовой дебаггинг простых, казалось бы, программ. На элементарные скрипты в 100 строк кода можно потратить несколько часов, ведь каждый трейсбэк кажется огромным и слишком насыщенным. Способность фильтровать такие данные без микрофрустраций формируется лишь спустя десятки часов отладки.
Справиться с негативом помогает конструкция try — except. В Python это лишь способ обработать ошибку и не «обронить» программу. Но если использовать ее не там и не так, лучше не станет (или вовсе будет хуже). Чтобы таких проблем не возникало, изучите этот гайд по применению обработчика.
Поначалу непросто запомнить, в каких ситуациях что возникает, а уже нужно вовсю обрабатывать исключения. Оттого люди разочаровываются в программировании: от джунов столь многое требуется в самом начале, причем неочевидно.
Вашему вниманию — мой личный топ самых частых исключений в дата-аналитике. Для каждой приведу примеры из своей практики.
ВРЕЗКА. Скажу честно, в первое время глаза разбегались при виде диаграммы исключений. Если хотите освежить в памяти полный перечень, обратитесь к статье.
Можно и нужно использовать try — except
KeyError
Если при чтении файла метод json.loads() возвращает вместо словаря список, то при попытке обратиться к ключу message можно схватить такое исключение:
Эту ошибку легко допустить, когда не знаешь тип возвращаемого объекта.
Представьте, что мы выгружаем логи бота по дням, а в выходные не случилось ни одной беседы. Тогда программа вернет объект None («ничего») про воскресенье, и у него тоже нет ключа ‘message’. Здесь try — except играет важную роль: навесив такой блок, мы обработаем ситуацию с пустотами:
IndexError
Допустим, мы и дальше получаем список реплик бота, причем каждый день длина этого перечня разная. Если все же приходится при создании цикла опираться на некую константу, которая с количеством реплик не всегда совпадает, try — except поможет справиться с ошибкой индекса:
Указываем во второй части конструкции, с какой ошибкой может столкнуться скрипт:
ВРЕЗКА. Это пример, за который коллеги поопытнее могут закидать меня камнями, ибо от таких констант вообще стоит избавляться. Но не всегда мы пишем код, который потом не нужно рефакторить.
TypeError + ValueError
Если вы, скажем, планируете оперировать тем, что ввел пользователь, то input() может сыграть с вами злую шутку:
По умолчанию метод возвращает строку, а мы-то предполагаем целочисленное значение:
try, в принципе, может справиться с такой ситуацией, если вы понимаете типы данных для проводимых операций (в данном случае, сложения):
Бонусный прием
В PEP 654 были объявлены группы исключений (Exception Groups): они позволяют заложить в одну строку except сразу несколько типов ошибок:
Если исследовать типы ошибок нет времени, можно на скорую руку заложить в такую группу все популярные ошибки и обернуть блоком try — except всю программу:
Не стоит использовать try — except
AttributeError
Представим, что мы храним текстовые документы в специализированной базе: текст (text) и координаты его вектора в многомерном пространстве (values):
Библиотека langchain, когда запрашивает близкие по смыслу предложения, ищет близконаправленные вектора и возвращает список документов res в преобразованном виде:
Если по квадратным скобкам узнать список в этом выводе можно, то определить, что каждый элемент — кортеж, уже сложнее. Блок try в таких ситуациях малоприменим, ибо тип данных задан автором библиотеки. Не ясно, какую ошибку класть в except.
Потому встроенная функция type() должна стать завсегдатаем в коде в первый год обучения:
ImportError
Те из нас, кто привык работать в ноутбуках на базе Google Colaboratory / Jupyter Notebook, помнят, что в среду предустановлено множество популярных сторонних инструментов, и дополнительно их устанавливать командой pip не нужно.
При работе с классической Python-программой легко забыть, что тот или иной инструмент не подключен. Или, что еще хуже, для данной версии Python не предусмотрена конкретная версия библиотеки. Недавно при запуске скрипта с langchain на Python 3.9. я была вынуждена обновлять языковой пакет до 3.11.5, ибо нужная langchain==0.0.194 в 3.9 попросту недоступна.
Для таких ситуаций try — except малополезен. С подключаемыми инструментами все равно придется разбираться вручную. Если в вашей практике есть пример, когда ImportError удалось отхэндлить с помощью try, поделитесь в комментариях.
Прерывание с клавиатуры (KeyboardInterrupt)
В этом случае обработка try нужна, только если вы хотите замучать коллегу-джуна, который еще не знает, что прерывание комбинацией Ctrl + C можно тоже обработать при исполнении программы. В остальном этого исключения редко добиваются после деплоя.
Заключение
Давайте вкратце повторим, когда применять конструкцию try — except, а когда лучше избегать:
2К открытий9К показов