Вопрос с собеседования · Python

Как работают try, except, else и finally?

JuniorИсключения и контекстные менеджеры
Ещё спрашивают так:
  • Когда выполняется блок else в try?
  • Зачем нужен finally?
  • Почему нельзя писать голый except?
  • Как создать своё исключение?
Коротко

try — опасный код, except — обработка, else — если ошибки не было, finally — всегда.

  • Ловите конкретные исключения, а не except: и не Exception без нужды
  • raise ... from e сохраняет причину исходной ошибки

А ещё Свои исключения наследуют от Exception, обычно с общим базовым классом проекта

Подробно

Порядок выполнения:

  1. выполняется блок try;
  2. если возникло исключение, ищется первый подходящий except (по типу, с учётом наследования) — поэтому более частные исключения пишут выше;
  3. если исключения не было, выполняется else;
  4. в любом случае в конце выполняется finally — даже при return или необработанной ошибке.

Зачем else: в try оставляют только строку, которая может упасть, а продолжение кладут в else. Так случайно не перехватится ошибка из кода, который вы не собирались защищать.

Зачем finally: освобождение ресурсов — закрыть файл, соединение, снять блокировку. Чаще для этого используют with.

Почему плох голый except:: он ловит всё, включая KeyboardInterrupt и SystemExit, и прячет ошибки. except Exception лучше, но тоже скрывает баги, если за ним нет логирования или повторного raise.

raise NewError(...) from e связывает исключения: в трейсбеке видна исходная причина. Свои исключения делают наследниками Exception — обычно от общего класса проекта (class AppError(Exception)), чтобы их можно было ловить вместе.

Пример

class ConfigError(Exception):
    pass

def load(path):
    try:
        f = open(path, encoding="utf-8")
    except FileNotFoundError as e:
        raise ConfigError(f"нет файла {path}") from e
    else:
        with f:
            return f.read()
    finally:
        print("попытка загрузки завершена")

Что хотят услышать

  • Порядок выполнения всех четырёх блоков.
  • Назначение else и finally на примерах.
  • Почему нельзя ловить всё подряд.
  • Свои исключения и raise ... from.

Частые ошибки

  • Писать except Exception: pass.
  • Ставить общий except Exception выше частных — частные никогда не сработают.
  • Думать, что finally не выполнится при return внутри try.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗else выполняется, если было исключение
  • ✗finally выполняется, только если исключения не было
  • ✓else — если ошибки не было, finally — всегда
  • ✗Лучше всегда ловить голый except:

Что спросят дальше

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования