У меня это пробурено в голову, что (по крайней мере, на PHP) это badbadmojo использовать try... catch
блоки для управления потоком. То, что я узнал, это использовать их только для обработки непредвиденных ошибок , а не для определения логического потока программы, потому что блоки catch
являются дорогостоящими.
Теперь, когда я изучаю python, я вижу множество исключений во всем мире и принцип EAFP . Означает ли это, что python более эффективен при обработке исключений, поэтому мне не нужно так беспокоиться о них для управления потоком, или этот принцип все еще стоит? Если нет, то PHP является исключением из нормы (по сравнению с другими языками) или Python?
Исторически, в таких языках, как C ++, исключения были очень медленными по сравнению с другими формами управления потоком на одном языке .
В C ++ работают две вещи:
Это несоответствие в производительности привело к общей мудрости за исключениями: делайте это только для необычных вещей, поэтому она используется только там, где это наиболее полезно, а не там, где это может повредить производительность.
Это не относится к языкам высокого уровня. Это также по двум причинам:
Исключения все еще не являются бесплатными, но несоответствие уже не является чем-то, о чем можно так беспокоиться. Это означает, что общая мудрость, сформированная на C ++, здесь неверна. Исключения регулярно используются в нормальном потоке программы.
Фактически, они встроены в язык, в конструкции, которые вы используете все время. Каждый раз, когда вы используете итератор – каждый for x in xrange(1000)
, для завершения цикла используется исключение StopIteration
.
Выбирайте исключения или линейное управление потоком в Python, на основе которых имеет смысл. Не выбирайте на основе производительности, если только вы не находитесь во внутреннем цикле, где важна производительность; в этом случае, как всегда, профиль и выяснить, действительно ли это имеет значение.
(Я не могу говорить для PHP.)
Я не считаю, что EAFP поощряет использование исключений для контроля потока. Скорее, это говорит нам о том, что нам не нужно проверять наличие определенного ключа в словаре или свойстве объекта, прежде чем ссылаться на него.
Отбрасывание исключений в качестве альтернативы операторам if
или корректным инструкциям while
или вместо использования break
или continue
внутри цикла не относится к этой категории. Это ленивый, подверженный ошибкам прогамминг, которого следует избегать.
великий Алекс Мартелли дает хороший обзор EAFP против LBYL в книге «Python In A Nutshell». (Он сильно опирается на использование EAFP)
def worth чтение:
http://books.google.com/books?id=JnR9hQA3SncC&lpg=PA134&ots=JaaWGy-24u&dq=alex%20martelli%20eafp%20lbyl&pg=PA134#v=onepage&q&f=false
Чтобы ответить на вопрос: Да. Исключения на Python дешевы. Если тест по-прежнему дешевле, да, вы должны просто использовать исключения для «неожиданных» ситуаций, так как если бы вы ожидали, что код будет терпеть неудачу чаще всего, проверьте, прежде чем вы это сделаете. Поскольку if-check будет избегать также фактической попытки, а также повышения и улавливания исключения, это будет намного быстрее в ситуации, которая терпит неудачу. (Если, конечно, сам тест не стоит дорого).
Но нет смысла избегать исключений как таковых. Python не будет перетаскиваться в обход, потому что вы поймаете множество исключений.
И как обычно: оптимизация без профилирования преждевременна.
Существует специальное исключение, которое предполагается использовать только в обычном потоке выполнения: StopIteration
. Это означает, что создатель Python не считает, что накладные расходы исключений не соответствуют требованиям.
Является ли это потому, что обработка исключений uber-эффективна или остальная часть языка просто медленна путем сравнения – это еще один вопрос …
Я сделал немного больше чтения и понял еще одну важную вещь, о которой никто еще не упомянул: в Python нет различий между ошибками и исключениями. Я знал это, но я не думаю, что до сих пор понял это значение.
В PHP вы можете обернуть $page->GetContent();
в try...catch
блоки все, что вы хотите, но если $page
не является объектом, ваше приложение по-прежнему будет зависнуть с результирующей фатальной ошибкой. Поэтому в PHP (и на любом другом языке, где ошибки не могут быть обнаружены), вам нужен определенный уровень LBYL.
Питон в основном говорит: «Это глупо, я должен уловить их». Просто попробуйте сделать то, что вам нужно сделать, и справиться с любым выпадением в except
блоке.
Вот отличная статья об обработке исключений, с которой я столкнулся.