Какие исключения в Python не наследуются от класса Exception

Ответ

В Python существуют исключения, которые наследуются напрямую от BaseException, минуя Exception. Их не рекомендуется перехватывать стандартным блоком except Exception:, так как они сигнализируют о системных событиях, а не об ошибках в логике программы.

Ключевые примеры:

  • SystemExit: Вызывается функцией sys.exit() для штатного завершения программы.
  • KeyboardInterrupt: Возникает при нажатии Ctrl+C пользователем в терминале.
  • GeneratorExit: Сообщает о закрытии генератора.

Перехват этих исключений нарушает ожидаемое поведение программы (например, пользователь не сможет прервать выполнение скрипта).

Пример демонстрации:

import sys

try:
    print("Программа запущена. Нажмите Ctrl+C для прерывания...")
    # sys.exit() # Раскомментируйте, чтобы проверить SystemExit
    while True:
        pass
except Exception as e:
    # Этот блок НЕ сработает для KeyboardInterrupt или SystemExit
    print(f"Перехвачено стандартное исключение: {e}")
except BaseException as e:
    # А этот блок сработает
    print(f"Перехвачено базовое исключение: {type(e).__name__}. Программа завершается.")

Best practice: Избегайте конструкций except BaseException: или except:, если у вас нет веской причины для обработки системных событий завершения.

Ответ 18+ 🔞

А, слушай, вот есть в Питоне такая штука, блядь, про которую многие даже не в курсе. Есть исключения, которые наследуются прямо от BaseException, минуя, сука, обычный Exception. Их ловить через except Exception: — это как пытаться поймать пулю зубами, нихуя не выйдет. Они же не про ошибки в коде, они про системные пизюлины.

Вот главные затейники:

  • SystemExit: Это когда sys.exit() вызывают, типа «всё, ребята, спасибо, я пошёл».
  • KeyboardInterrupt: Это когда пользователь, этот хитрожопый, жмёт Ctrl+C в терминале, типа «надоело, вырубай».
  • GeneratorExit: Это когда генератору намекают, что пора на пенсию, закрывают его.

Если их ловить как обычные исключения — это ж пиздец, программа превратится в зомби. Пользователь будет долбить Ctrl+C, а она, сука, как ни в чём не бывало продолжит работать, будто ей похуй.

Вот, смотри, как это выглядит на практике:

import sys

try:
    print("Программа запущена. Нажмите Ctrl+C для прерывания...")
    # sys.exit() # Раскомментируйте, чтобы проверить SystemExit
    while True:
        pass
except Exception as e:
    # Этот блок НЕ сработает для KeyboardInterrupt или SystemExit
    print(f"Перехвачено стандартное исключение: {e}")
except BaseException as e:
    # А этот блок сработает
    print(f"Перехвачено базовое исключение: {type(e).__name__}. Программа завершается.")

А теперь золотое правило, ёпта: Не лезь со своим except BaseException: или, упаси боже, голым except:, если тебе реально не нужно управлять концом света в твоей программе. Это как давать ребёнку гранату — вроде игрушка, а потом овердохуища проблем.