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 result
realmente contenha algo iterável, eu usaria a try/except
abordagem. Será mais rápido se as exceções forem realmente excepcionais. Se result
for None
mais de 50% do tempo, o uso if
provavelmente 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 if
declaração sempre lhe custa, é quase livre configurar um try/except
bloco. Mas quando Exception
realmente ocorre, o custo é muito maior.
Moral:
- É perfeitamente aceitável (e "pitônico") usar
try/except
no controle de fluxo,
- mas faz mais sentido quando
Exception
s 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
try
e except
declarações. A técnica contrasta com o
estilo LBYL comum a muitos outros idiomas, como C.