Ответ
Иерархия исключений в Python — это древовидная структура встроенных классов, где все исключения наследуются от базового класса BaseException. Понимание этой иерархии позволяет писать более точный и надежный код для обработки ошибок.
Структура иерархии
Ключевые классы в иерархии организованы следующим образом:
BaseException
├── SystemExit
├── KeyboardInterrupt
└── Exception
├── ArithmeticError
│ ├── ZeroDivisionError
│ └── OverflowError
├── AssertionError
├── AttributeError
├── LookupError
│ ├── IndexError
│ └── KeyError
└── ValueError
Ключевые принципы
- Наследование: Все исключения являются потомками
BaseException. - Перехват: Блок
exceptперехватывает как указанный класс исключения, так и всех его потомков. Это позволяет обрабатывать группы ошибок (например,except LookupError:ловит иIndexError, иKeyError). - Пользовательские исключения: Рекомендуется создавать свои классы исключений, наследуя их от
Exceptionили его потомков, но не отBaseException. BaseException: ПерехватBaseException— плохая практика, так как он включает системные сигналы выхода (SystemExit,KeyboardInterrupt), которые обычно не должны подавляться.
Пример обработки
Порядок блоков except важен: от более конкретного к более общему.
data = {'key': 'value'}
try:
# Попытка доступа по несуществующему ключу
print(data['missing_key'])
except KeyError as e:
# Этот блок сработает, так как KeyError - более специфичное исключение
print(f"Ошибка доступа к ключу: {e}")
except LookupError as e:
# Этот блок не сработает, так как KeyError (потомок LookupError) уже был перехвачен
print(f"Общая ошибка поиска: {e}") Ответ 18+ 🔞
А, ну ты глянь, какая тут хуйня интересная вырисовывается! В Питоне, блядь, все эти ошибки, которые вылетают и заставляют тебя материться в три часа ночи — они не просто так, у них там целая родословная, как у английских лордов, ёпта! Дерево, сука, генеалогическое, где на самом верху сидит папаша BaseException и смотрит на всех свысока.
Вот смотри, как это устроено, блядь:
BaseException (Это типа царь-батюшка всех косяков)
├── SystemExit (Это когда скрипт вежливо просится на выход)
├── KeyboardInterrupt (А это когда ты в ярости жмёшь Ctrl+C)
└── Exception (А вот это уже наша, родная, рабочая банда ошибок!)
├── ArithmeticError (Туплю с математикой)
│ ├── ZeroDivisionError (Пытаюсь поделить на ноль, как дебил)
│ └── OverflowError (Переполнил, блядь, всё, что можно)
├── AssertionError (А вот это я сам себя обманул, говоря 'я уверен!')
├── AttributeError (Полез к объекту за свойством, которого у него нет)
├── LookupError (Ищу что-то не там, где надо)
│ ├── IndexError (Полез в список за сотым элементом, а там три)
│ └── KeyError (Полез в словарь за ключом, а его там, блядь, и не пахло)
└── ValueError (Подсунул функции какую-то дичь вместо нормального значения)
И вся фишка в чём, блядь? В том, что когда ты пишешь except, ты ловишь не только ту самую ошибку, но и всех её детишек! Это как крикнуть "Петров, ко мне!" — и прибежит не только Петров, но и все его младшие братья-недоучки. Поэтому если поймал LookupError, то и IndexError, и KeyError уже в кармане, ёпта!
Но главное правило, блядь, которое мозги не выносит: НЕ ЛОВИ BaseException! Это пиздец какой-то! Ты ж тогда и KeyboardInterrupt поймаешь, и пользователь уже не сможет твой зависший скрипт остановить, будет сидеть и материться, пока батарейка не сядет. Лови всегда от Exception и ниже, понял? И свои косяки создавай, наследуя от них же, а не от царя-батюшки.
А вот смотри, как это на практике выглядит, чтобы не быть, прости господи, распиздяем:
data = {'key': 'value'} # Словарик, в нём одна парочка
try:
# А я возьму и попробую вытащить то, чего нет! Гений, блядь!
print(data['missing_key'])
except KeyError as e:
# Опа! Словил конкретно KeyError! Он самый первый в очереди на поимку.
print(f"Ошибка доступа к ключу: {e}") # Скажу себе, что я идиот.
except LookupError as e:
# А этот блок уже проспал всё веселье. KeyError — его сын, его уже поймали раньше.
# Сюда мы не попадём, даже не мечтай.
print(f"Общая ошибка поиска: {e}")
Вот и вся магия, блядь. Сначала лови мелких воришек, а потом уже, если что, заграбастывай целую шайку. А то так и до BaseException докатишься, а потом будешь сидеть и думать, почему скрипт не реагирует ни на что, кроме выключения компа топором.