2.25. Tratamento de erros¶
A maioria dos problemas em tempo de execução no Python se manifesta como exceções – uma forma nomeada e estruturada de relatar que algo deu errado. ValueError, TypeError, KeyError, OSError, MemoryError são todos exemplos; cada um é uma classe, e lançar uma delas interrompe a chamada atual e procura um tratador no código ao redor.
2.25.1. try / except¶
Envolva um bloco de código em try para capturar qualquer exceção que ele lance:
try:
n = int(input_text)
except ValueError:
n = 0
Se a conversão int(...) falhar, o controle salta para o bloco except em vez de propagar o erro adiante. Se input_text for uma string de inteiro válida, o bloco except é pulado.
Um único try pode ter vários blocos except, cada um capturando um tipo diferente de erro:
try:
value = data[key]
except KeyError:
value = None
except TypeError:
value = -1
O Python casa em ordem; o primeiro cuja classe de exceção se encaixa trata o problema. Capturar Exception (a classe base de quase tudo) trata qualquer erro; reserve isso para a camada mais externa de um programa, onde a alternativa seria uma falha.
Aviso
Um except: simples (sem classe após a palavra-chave) também captura KeyboardInterrupt – a exceção que a IDE envia quando você pressiona o botão stop para interromper um script em execução. Um laço envolto em um except: pass simples vai engolir a interrupção e continuar rodando, sem deixar nenhuma forma de parar o script a não ser desligando e ligando a energia.
Prefira except Exception: em vez de um except: simples quando você realmente precisar capturar de forma ampla. KeyboardInterrupt herda de BaseException, não de Exception, então except Exception: deixa o botão stop funcionando.
2.25.1.1. Inspecionando a exceção¶
Para ler a mensagem associada a uma exceção, nomeie-a com as:
try:
f = open("data.txt")
except OSError as e:
print("could not open file:", e)
A variável associada por as só é válida dentro do bloco except.
2.25.2. else e finally¶
Um bloco try tem dois extras opcionais.
O else é executado somente quando o try termina sem lançar uma exceção:
try:
value = compute()
except ValueError:
print("bad input")
else:
print("got", value)
Colocar “o que fazer quando deu certo” no else mantém o bloco try enxuto – apenas a linha que pode falhar pertence ao try.
O finally é executado ao final aconteça o que acontecer – quer o try tenha tido sucesso, quer tenha lançado e sido tratado, quer tenha lançado e esteja prestes a propagar:
try:
do_work()
finally:
cleanup()
O finally sempre é executado. O else só é executado no caminho sem exceção.¶
Para a maioria dos padrões de adquirir/liberar, prefira um gerenciador de contexto em vez de um par try / finally – o próprio recurso gerencia sua limpeza.
2.25.3. Exceções embutidas comuns¶
Uma lista curta das exceções que você encontrará com frequência:
ValueError– tipo certo, valor errado (bytes([300])– 300 é do tipo certo, mas está fora do intervalo válido de bytes de 0..255).TypeError– tipo totalmente errado (len(42)).IndexError– índice além do fim de uma sequência.AttributeError– acessar um atributo que não existe ("abc".foo).OSError– uma falha de sistema de arquivos ou de E/S.MemoryError– ficou sem heap. Em um ambiente de execução com memória restrita, isso pode acontecer durante a operação normal – não apenas em casos patológicos.