Иногда исключения самые быстрые. Я видел случаи, когда исключения нулевых объектов были быстрее даже в Java, чем при использовании управляющих структур (в данный момент я не могу процитировать исследование, поэтому вам придется мне доверять). Проблема возникает, когда Java фактически требует времени и заполняет трассировку стека пользовательского класса исключений вместо использования собственных (которые, по-видимому, по крайней мере частично кэшированы). Прежде чем сказать, что что-то происходит в одностороннем порядке быстрее или медленнее, было бы хорошо для сравнения.
В Python это не только быстрее, но и гораздо правильнее сделать что-то, что может вызвать исключение, а затем обработать ошибку. Да, вы можете применять систему типов, но это противоречит философии языка - вместо этого вы должны просто попытаться вызвать метод и поймать результат! (Проверка, является ли файл доступным для записи, похожа - просто попробуйте записать в него и поймать ошибку).
Я видел случаи, когда быстрее было бы сделать что-то глупое, например таблицы запросов, которых там не было, чем выяснить, существует ли таблица в PHP + MySQL ( вопрос, где я проверяю это, на самом деле мой единственный принятый ответ с отрицательным голосом) ,
Все это говорит о том, что использование исключений должно быть ограничено по нескольким причинам:
- Случайное глотание вложенных исключений. Это главное. Если вы поймете какое-то глубоко вложенное исключение, с которым пытается справиться кто-то другой, вы только что застрелили своего коллегу-программиста (возможно, даже вас!) В ногу.
- Тесты становятся неочевидными. Блок кода, в котором есть исключение, может иметь одну из нескольких ошибок. С другой стороны, логическое значение, хотя теоретически это может раздражать отладку, обычно это не так. Это особенно верно, поскольку
try...catch
сторонники потока управления обычно (по моему опыту) не следуют философии «минимизировать код в блоке попытки».
- Это не позволяет для
else if
блока. Достаточно сказано (и если кто-то возражает с «Но они могут использовать разные классы исключений», мой ответ: «Иди в свою комнату и не выходи, пока не подумаешь о том, что сказал»).
- Это вводит в заблуждение грамматически.
Exception
для остального мира (как не для приверженцев try...catch
философии потока управления) означает, что что-то вошло в нестабильное (хотя, возможно, восстанавливаемое) состояние. Нестабильные состояния - ПЛОХО, и это должно держать нас всех ночью, если у нас действительно есть исключения, которых можно избежать (это на самом деле меня пугает, нет лжи).
- Это не соответствует общему стилю кодирования. Наша работа как с нашим кодом, так и с нашим пользовательским интерфейсом состоит в том, чтобы сделать мир как можно более очевидным.
try...catch
поток управления идет вразрез с тем, что обычно считается наилучшей практикой. Это означает, что новичку в проекте потребуется больше времени, чтобы изучить проект, что означает увеличение количества человеко-часов без какой-либо выгоды.
- Это часто приводит к дублированию кода. Наконец, блоки, хотя это и не является строго обязательным, должны разрешать все висячие указатели, которые были оставлены открытыми прерванным блоком try. Так что попробуйте блоки. Это означает, что вы можете иметь
try{ obj.openSomething(); /*something which causes exception*/ obj.doStuff(); obj.closeSomething();}catch(Exception e){obj.closeSomething();}
. В более традиционном if...else
сценарии closeSomething()
копирование и вставка менее вероятно (опять же, из личного опыта). (Следует признать, что этот конкретный аргумент больше связан с людьми, с которыми я встречался, чем с реальной философией).