Вы часто слышите, что Python поощряет стиль EAFP («проще попросить прощения, чем разрешения»), а не стиль LBYL («посмотрите, прежде чем прыгнуть»). Для меня это вопрос эффективности и удобочитаемости.
В вашем примере (скажем, что вместо возврата списка или пустой строки функция должна была вернуть список или None), если вы ожидаете, что 99% времени на resultсамом деле будет содержать что-то итеративное, я бы использовал этот try/exceptподход. Будет быстрее, если исключения действительно будут исключительными. Если resultэто Noneболее 50% случаев, то, ifвероятно, лучше использовать.
Чтобы подтвердить это с помощью нескольких измерений:
>>> import timeit
>>> timeit.timeit(setup="a=1;b=1", stmt="a/b")
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для управления потоком,
- но это имеет смысл больше всего, когда
Exceptions на самом деле исключительны.
Из документов Python:
EAFP
Проще просить прощения, чем разрешения. Этот общий стиль кодирования Python предполагает наличие действительных ключей или атрибутов и перехватывает исключения, если предположение оказывается ложным. Для этого чистого и быстрого стиля характерно наличие множества
tryи exceptвысказываний. Эта техника контрастирует со
стилем LBYL, общим для многих других языков, таких как C.