Как использовать try — except и не испортить себе жизнь

Posted by

Зачастую новичков в 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, а когда лучше избегать:

!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *