Гид по технологиям

Обработка исключений в Python

5 min read Python Обновлено 08 Jan 2026
Обработка исключений в Python: руководство и шаблоны
Обработка исключений в Python: руководство и шаблоны

Руки печатают на ПК, рядом книга по Python

Обработка исключений — это способность перехватывать и управлять ошибочными ситуациями в программе, показывать понятные сообщения и гарантировать, что ресурсы корректно освобождаются. Независимо от того, создаёте ли вы веб-сайт, API или модуль, ясная обработка ошибок улучшает опыт пользователя и облегчает отладку.

Как работают исключения в Python

Когда вы «поднимаете» (raise) исключение, вы говорите интерпретатору прервать нормальный поток выполнения и перейти к ближайшему обработчику исключений. Метафорически это похоже на попытку поднять тяжесть: если не получается, нужно сообщить об этом — и обработчик выполняет эту роль.

Типичная конструкция для обработки выглядит так:

try:  
    "code to be executed"  
except:  
    "error message"  

Вы также можете добавлять блок finally — код в нём выполняется всегда, независимо от того, было исключение или нет. Это удобно для освобождения ресурсов (закрыть файл, закрыть соединение и т. п.).

Пример с finally:

try:  
    print(9+6)  
except:  
    print("error message")  
finally:  
    print("please restart")  
  
Вывод:  
15  
please restart   

Блок else выполняется только если внутри try исключений не произошло — удобно для кода, который должен выполняться только при успехе основной операции.

try:  
    C = 2 + B  
except:  
    print("B needs to be defined")  
else:  
    print(u"Added successfully! The result is %s"%(C))  
  
Вывод: B needs to be defined  

Если определить B и повторить:

try:  
    B = 5  
    C = 2 + B  
except:  
    print("B needs to be defined")  
else:  
    print(u"Added successfully! The result is %s"%(C))  
  
Вывод: Added successfully! The result is 7  

Когда использовать исключения

Исключения — мощный инструмент, но их нельзя использовать как замену контролю корректности данных во всём коде. Рекомендации:

  • Используйте исключения для обработки непредвиденных ситуаций или ошибок ввода от пользователя и внешних систем.
  • Не подавляйте ошибки полностью — логируйте их или пробрасывайте дальше после частичной обработки.
  • Не применяйте «голый» except: он скрывает тип ошибки и затрудняет отладку.

В общем, исключения удобны для обработки ошибок внешнего происхождения (ввод, сеть, файл), а для локальной валидации полезнее явные проверки.

Приёмы обработки исключений — практические примеры

Ниже — перевод и сохранение исходных примеров с пояснениями.

try:  
    C = 2 + B  
except NameError as err:  
    print(err, ":", "B needs to be defined, please")  
else:  
    print(u"Added successfully! The result is %s"%(C))  
  
Вывод: name 'B' is not defined : B needs to be defined, please  

В этом примере используется конкретный тип исключения NameError — это хорошая практика: сначала проверяем стандартное исключение, затем дополняем сообщение своим текстом.

Можно перехватывать несколько исключений отдельно:

try:  
    B = 5  
    C = 2 + B  
    D = float(6)  
    F = 7/0  
  
except NameError as err:  
    print(err,":", "B needs to be defined, please")  
except ValueError as val:  
    print(val,":", "You can't convert that data")  
except ZeroDivisionError as zeroerr:  
    print(zeroerr,":", "You can't divide a number by zero")  
else:  
    print(u"Operation successfull! The results are: %s, %s, and %s"%(C, D, F))  
  
Вывод: division by zero : You can't divide a number by zero  

Если операция деления допустима (например, 7/5), то выполнится блок else и покажет результаты.

Пользовательские исключения

Иногда нужна собственная семантика ошибки — для этого определяют классы исключений, унаследованные от Exception.

class connectionError(RuntimeError):  
   def __init__(self, value):  
      self.value = value  
try:  
   raise connectionError("Bad hostname")  
except connectionError as err:  
   print(err.value)  
  
Вывод: Bad hostname  

Или более гибкий пример с передачей сообщения:

class errors(Exception):  
    pass  
  
class sixFiveError(errors):  
   def __init__(self, value, message):  
      self.value = value  
      self.message = message  
try:  
   raise sixFiveError(6-5,"This substraction is not allowed")  
except sixFiveError as e:  
   print("There was an error:", e.message)  
  
Вывод: There was an error: This substraction is not allowed  

Пример функции, которая поднимает пользовательское исключение при попытке сложить не float-значения:

# First call the base exception classes:  
  
class errors(Exception):  
    pass  
  
# Next, derive your own exception from the base class:  
  
class FloatError(errors):  
   def __init__(self, value, message):  
      self.value = value  
      self.message = message  
  
# Create a function to add two floats:  
def addTwoFloat(a, b):  
if (type(a) and type(b)) != float:  
raise FloatError(a+b,"Numbers must be float to add")  
else:  
        print(a + b)  
  
addTwoFloat(4, 7)  
  
Вывод: __main__.FloatError: (11, 'Numbers must be float to add')  

Важно: пользовательские исключения видны только в том модуле, где они определены, если вы явно не импортируете их.

Лучшие практики и шаблоны

  • Перехватывайте самые конкретные исключения, а не все подряд.
  • Избегайте пустого except: используйте except Exception as e, а ещё лучше — конкретный тип.
  • Логируйте трассировки ошибок (traceback) — это поможет при диагностике.
  • Не используйте исключения для управления обычным потоком программы (используйте проверки).
  • При создании пользовательских исключений наследуйте от Exception или от подходящего подкласса.
  • Добавляйте понятные сообщения ошибок, ориентированные на пользователя или на лог для разработчика.

Пример рекомендованного шаблона:

import logging

logger = logging.getLogger(__name__)

try:
    result = do_io_operation()
except (IOError, OSError) as e:
    logger.exception("Ошибка ввода-вывода при do_io_operation: %s", e)
    raise
else:
    return result
finally:
    cleanup()

Когда исключения не подходят

  • Для внутренней валидации данных лучше явные проверки (if/else), если это ожидаемая ситуация.
  • Для высокопроизводительных циклов частые поднятия исключений могут быть дороже, чем проверка условий заранее.
  • Если исключение локализуется и не несёт полезной информации — лучше вернуть специальный код ошибки или объект результата с полем status.

Альтернативные подходы

  • Возврат объектов результата (Result/Either pattern) вместо исключений — чаще используется в функциональном стиле.
  • Контроль потоков с помощью валидации и предварительных проверок.
  • Использование типов и проверок (typing, pydantic) для ловли ошибок на этапе разработки.

Ментальные модели и эвристики

  • «Проверяй заранее или обрабатывай исключение» — choose: EAFP (Easier to Ask Forgiveness than Permission) vs LBYL (Look Before You Leap). Python склоняется к EAFP: пробуй и обрабатывай исключения, если операция обычно успешна.
  • Делайте ошибки явными: пользователь должен понять причину и, если возможно, как её исправить.

Чеклист по ролям

Разработчик:

  • Перехватить конкретные исключения.
  • Логировать с трассировкой.
  • Не скрывать исключения.

Тестировщик:

  • Проверить сценарии ошибок: ввод, сеть, диск.
  • Убедиться, что сообщения пользователю понятны.

DevOps/инфраструктура:

  • Настроить сбор логов и алерты по критическим исключениям.
  • Отслеживать повторяющиеся ошибки и их частоту.

Критерии приёмки

  • При некорректном вводе пользователь получает понятное сообщение и инструкция по исправлению.
  • Системные исключения логируются с traceback и метаданными (время, идентификатор запроса).
  • Ресурсы (файлы, соединения) всегда освобождаются.

Шпаргалка по стилю кода

  • Не используйте bare except.
  • Используйте context managers (with) для файлов и сетевых соединений.
  • Для пользовательских ошибок создавайте небольшие и семантически значимые классы исключений.

Пример context manager:

with open('data.txt') as f:
    process(f)

Диаграмма принятия решения

flowchart TD
  A[Начать операцию] --> B{Ожидается ошибка?}
  B -- Да --> C[Проверить условие заранее]
  C --> D{Условие прошло?}
  D -- Да --> E[Выполнить операцию]
  D -- Нет --> F[Вернуть ошибку/код]
  B -- Нет --> G[Попробовать выполнить]
  G --> H{Исключение поднято?}
  H -- Да --> I[Перехватить конкретное исключение]
  I --> J[Залогировать, сообщить пользователю, при необходимости пробросить]
  H -- Нет --> E

Тестовые сценарии и кейсы

  • Попытка открыть несуществующий файл должна вызывать OSError, сообщение логируется, пользователь получает дружелюбный текст.
  • Деление на ноль вызывает ZeroDivisionError; при этом сервис должен сообщить о некорректных данных, не падать.
  • Неправильный тип в API-запросе должен возвращать 4xx с описанием ошибки.

Краткий глоссарий

  • Исключение — сигнал о непредвиденной ситуации во время выполнения программы.
  • raise — оператор для явного поднятия исключения.
  • try — блок, где выполняется потенциально опасный код.
  • except — блок, который перехватывает исключения.
  • finally — блок, выполняемый всегда.
  • пользовательское исключение — класс исключения, определённый разработчиком.

Заключение

Исключения — стандартный инструмент управления ошибками в Python. Правильное использование try/except/else/finally, создание осмысленных пользовательских исключений и хорошая практика логирования делают ваш код надёжнее и понятнее пользователю. Выберите стратегию (EAFP или LBYL) в зависимости от сценариев и нагрузки, и придерживайтесь конкретных перехватов вместо голых except.

Краткое резюме:

  • Перехватывайте конкретные исключения.
  • Логируйте и давайте понятные сообщения.
  • Используйте пользовательские исключения для бизнес-логики.
  • Тестируйте сценарии ошибок и освобождение ресурсов.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство