Вы часто слышите, что Python поддерживает стиль EAFP («проще просить прощения, чем разрешения») в стиле LBYL («смотри, прежде чем прыгнуть»). Для меня это вопрос эффективности и читабельности.
В вашем примере (скажем, вместо того, чтобы возвращать список или пустую строку, функция должна была возвращать список или None
), если вы ожидаете, что 99% времени result
будет действительно содержать что-то итеративное, Я бы использовал try/except
подход. Это будет быстрее, если исключения действительно являются исключительными. Если result
равен None
более чем в 50% случаев, тогда лучше использовать if
.
Чтобы подтвердить это несколькими измерениями:
>>> import timeit
>>> timeit.timeit(setup="a=1;b=1", stmt="a/b") # no error checking
0.06379691968322732
>>> timeit.timeit(setup="a=1;b=1", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.0829463709378615
>>> timeit.timeit(setup="a=1;b=0", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.5070195056614466
>>> timeit.timeit(setup="a=1;b=1", stmt="if b!=0:\n a/b")
0.11940114974277094
>>> timeit.timeit(setup="a=1;b=0", stmt="if b!=0:\n a/b")
0.051202772912802175
Итак, в то время как оператор if
всегда стоит вам, установить блок try/except
практически бесплатно. Но когда Exception
действительно происходит, стоимость намного выше.
Мораль:
- Совершенно нормально (и «питонно») использовать
try/except
для управления потоком,
- но это имеет смысл больше всего, когда
Exception
на самом деле исключительны.
Из документов Python:
ЭСПЦ
Проще просить прощения, чем
разрешение. Это обычное Python-кодирование
стиль предполагает наличие действительного
ключи или атрибуты и ловит
исключения, если предположение оказывается
ложный. Этот чистый и быстрый стиль
характеризуется наличием многих
try
и except
операторы.
техника контрастирует с LBYL
стиль, общий для многих других языков
такие как C.