Você costuma ouvir que o Python incentiva o estilo EAFP ("é mais fácil pedir perdão do que permissão") sobre o estilo LBYL ("veja antes de pular"). Para mim, é uma questão de eficiência e legibilidade.
No seu exemplo (digamos que, em vez de retornar uma lista ou uma sequência vazia, a função retornasse uma lista ou None), se você espera que 99% do tempo resultrealmente contenha algo iterável, eu usaria a try/exceptabordagem. Será mais rápido se as exceções forem realmente excepcionais. Se resultfor Nonemais de 50% do tempo, o uso ifprovavelmente será melhor.
Para suportar isso com algumas medidas:
>>> 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
Portanto, enquanto uma ifdeclaração sempre lhe custa, é quase livre configurar um try/exceptbloco. Mas quando Exceptionrealmente ocorre, o custo é muito maior.
Moral:
- É perfeitamente aceitável (e "pitônico") usar
try/exceptno controle de fluxo,
- mas faz mais sentido quando
Exceptions são realmente excepcionais.
Nos documentos do Python:
EAFP
Mais fácil pedir perdão do que permissão. Esse estilo comum de codificação Python pressupõe a existência de chaves ou atributos válidos e captura exceções se a suposição for falsa. Este estilo limpo e rápido é caracterizado pela presença de muitos
trye exceptdeclarações. A técnica contrasta com o
estilo LBYL comum a muitos outros idiomas, como C.