O principal argumento do livro é que a versão de exceção do código é melhor, pois ela captura tudo o que você pode ter esquecido se tentar escrever sua própria verificação de erro.
Penso que esta afirmação é verdadeira apenas em circunstâncias muito específicas - nas quais você não se importa se a saída está correta.
Não há dúvida de que levantar exceções é uma prática sólida e segura. Você deve fazer isso sempre que achar que há algo no estado atual do programa com o qual você (como desenvolvedor) não pode ou não deseja lidar.
Seu exemplo, no entanto, é sobre a captura de exceções. Se você capturar uma exceção, não estará se protegendo de cenários que possa ter esquecido. Você está fazendo exatamente o oposto: assume que não ignorou nenhum cenário que possa ter causado esse tipo de exceção e, portanto, está confiante de que está tudo bem em capturá-la (e, assim, impedir que o programa saia, como qualquer exceção não capturada).
Usando a abordagem de exceção, se você vir a ValueError
exceção, pule uma linha. Usando a abordagem tradicional de não exceção, você conta o número de valores retornados split
e, se for menor que 2, pula uma linha. Você deve se sentir mais seguro com a abordagem de exceção, pois pode ter esquecido outras situações de "erro" em sua verificação de erro tradicional e as except ValueError
capturaria para você?
Isso depende da natureza do seu programa.
Se você estiver escrevendo, por exemplo, um navegador da Web ou um reprodutor de vídeo, um problema com entradas não deve causar o travamento de uma exceção não detectada. É muito melhor produzir algo remotamente sensato (mesmo que, estritamente falando, incorreto) do que sair.
Se você estiver escrevendo um aplicativo em que a correção é importante (como software comercial ou de engenharia), essa seria uma abordagem terrível. Se você se esqueceu de algum cenário que levanta ValueError
, a pior coisa a fazer é ignorar silenciosamente esse cenário desconhecido e simplesmente pular a linha. É assim que erros muito sutis e caros acabam no software.
Você pode pensar que a única maneira de ver ValueError
neste código é se for split
retornado apenas um valor (em vez de dois). Mas e se a sua print
declaração mais tarde começar a usar uma expressão que aumenta ValueError
sob algumas condições? Isso fará com que você pule algumas linhas não porque elas falham :
, mas porque print
falham nelas. Este é um exemplo de um bug sutil ao qual me referi anteriormente - você não notaria nada, apenas perderia algumas linhas.
Minha recomendação é evitar capturar (mas não gerar!) Exceções no código em que produzir saída incorreta é pior do que sair. A única vez em que capturava uma exceção nesse código é quando tenho uma expressão verdadeiramente trivial, para que eu possa facilmente raciocinar o que pode causar cada um dos possíveis tipos de exceção.
Quanto ao impacto no desempenho do uso de exceções, é trivial (em Python), a menos que exceções sejam encontradas com freqüência.
Se você usar exceções para lidar com condições que ocorrem rotineiramente, em alguns casos poderá pagar um enorme custo de desempenho. Por exemplo, suponha que você execute remotamente algum comando. Você pode verificar se o texto do seu comando passa pelo menos na validação mínima (por exemplo, sintaxe). Ou você pode esperar que uma exceção seja levantada (o que ocorre apenas depois que o servidor remoto analisa seu comando e encontra um problema). Obviamente, o primeiro é ordens de magnitude mais rápidas. Outro exemplo simples: você pode verificar se um número é zero ~ 10 vezes mais rápido do que tentar executar a divisão e capturar a exceção ZeroDivisionError.
Essas considerações são importantes apenas se você enviar seqüências de comandos malformadas para servidores remotos ou receber argumentos de valor zero que você usa para divisão.
Nota: Presumo que você usaria em except ValueError
vez do justo except
; como outros apontaram, e como o próprio livro diz em algumas páginas, você nunca deve usar nada except
.
Outra observação: a abordagem adequada de não exceção é contar o número de valores retornados por split
, em vez de procurar :
. O último é muito lento, pois repete o trabalho realizado split
e pode quase dobrar o tempo de execução.