Menu

Exceções em Python: try, except, else, finally e raise

Como tratar erros em Python — try/except/finally, capturar exceções específicas, lançar as suas e quando deixar um erro propagar.

Erros são só valores com atitude ruim

Quando algo dá errado em Python — divisão por zero, ler um arquivo que não existe, parsear um número ruim — o runtime cria um objeto de exceção e começa a desenrolar a pilha de chamadas até algo capturar. Se nada captura, seu programa termina e imprime um traceback.

Exceções não são ruins em si. São o jeito do Python sinalizar "não consigo continuar com esta operação; aqui está por quê". Seu trabalho é decidir, caso a caso, quais você sabe se recuperar e quais deve deixar escalar.

O formato básico

main.py
Output
Click Run to see the output here.
  • try: abre o bloco de código arriscado.
  • except ValueError: captura essa exceção específica se for lançada dentro do try.
  • Se nenhuma exceção dispara, o except é pulado inteiro.

Rode o snippet com 42 — funciona. Rode com hello — o handler roda.

Capturando exceções específicas

O Python tem uma hierarquia de tipos de exceção. Algumas que você vai encontrar com frequência:

  • ValueError — um valor estava errado de algum jeito (int("abc"), argumentos fora de alcance).
  • TypeError — o tipo errado foi usado ("hi" + 3).
  • KeyError — uma chave de dict não foi encontrada.
  • IndexError — um índice de sequência estava fora de alcance.
  • FileNotFoundError — um arquivo não existe.
  • ZeroDivisionError — tentou dividir por zero.
  • AttributeError — um objeto não tem o atributo pedido.

Capture o específico que você sabe tratar:

main.py
Output
Click Run to see the output here.

Você pode capturar várias exceções numa cláusula passando uma tupla:

main.py
Output
Click Run to see the output here.

Repare as e. Isso amarra o objeto de exceção a e para você inspecionar a mensagem ou atributos.

Evite capturar tudo

Um except: vazio captura literalmente qualquer coisa, inclusive KeyboardInterrupt (seu Ctrl-C) e saídas em nível de sistema. Não use.

except Exception: é um pouco melhor, mas ainda perigoso — engole bugs que você não antecipou e esconde a fonte real dos problemas:

# Don't do this without a really good reason.
try:
    do_something()
except Exception:
    pass

A escolha certa é quase sempre capturar a exceção específica da qual você sabe se recuperar. Se uma exceção que você não esperava chega ao topo do seu programa, o traceback te diz exatamente o que deu errado — isso é feature, não bug.

else e finally

A instrução try tem mais duas cláusulas opcionais:

  • else roda se o bloco try terminou sem lançar.
  • finally roda não importa o quê — com ou sem exceção.
main.py
Output
Click Run to see the output here.

else é o lugar mais limpo para código "só em caso de sucesso" — você não quer que um bloco try faça mais do que a parte que pode falhar. finally é para limpeza que precisa rodar mesmo se o try falha: fechar um recurso, liberar um lock, restaurar estado.

Lançando exceções você mesmo

Use raise para sinalizar um erro no seu próprio código:

main.py
Output
Click Run to see the output here.

Escolha um tipo de exceção que bate com o que deu errado. Recorra aos embutidos primeiro — ValueError, TypeError, FileNotFoundError — antes de definir uma classe sua.

Definindo sua própria exceção

Quando os embutidos não capturam o significado, defina uma exceção customizada:

main.py
Output
Click Run to see the output here.

Herde de Exception (ou um embutido mais específico) e dê uma docstring à classe. Geralmente é tudo que você precisa. Exceções customizadas deixam quem chama capturar o erro com significado no domínio.

raise ... from ...: exceções encadeadas

Quando uma exceção dispara outra, mantenha a corrente:

main.py
Output
Click Run to see the output here.

O from e anexa o erro original. Quando o traceback imprime, o Python mostra os dois — o ConfigError que apareceu e o FileNotFoundError que causou. Esse tipo de rastro é inestimável para debug.

Context managers: o jeito mais limpo de limpar

finally está bem, mas para recursos como arquivos, um context manager (o que o with usa) é quase sempre melhor:

# finally version
f = open("data.txt")
try:
    data = f.read()
finally:
    f.close()

# with version
with open("data.txt") as f:
    data = f.read()

Os dois são seguros. A forma with é mais curta e se aplica automaticamente. Recorra a finally só quando está fazendo algo que a biblioteca padrão ainda não envolveu num context manager.

Quando não capturar

Capturar uma exceção é uma decisão — você está dizendo "sei tratar isso". Se você não sabe, deixe a exceção propagar. Código como este é quase sempre erro:

try:
    do_work()
except Exception:
    pass  # silently ignore everything

Silenciar erros torna bugs invisíveis. É melhor quebrar barulhento do que mancar num estado inconsistente.

Fechando

  • try/except te deixa tratar erros dos quais você consegue se recuperar.
  • Capture exceções específicas, não Exception em branco.
  • raise sinaliza erros no seu próprio código.
  • Blocos with substituem a maior parte da limpeza com finally.
  • Na dúvida, deixe a exceção propagar.

A seguir: um tour pelos erros específicos que o Python mais dispara — KeyError, ValueError, ModuleNotFoundError e mais alguns — mais os hábitos de debug que resolvem eles rápido.

Perguntas frequentes

Como trato erros em Python?

Envolva código arriscado num bloco try e capture a exceção específica num bloco except: try: risky() except ValueError: .... O else opcional roda se nenhuma exceção ocorreu; finally roda de qualquer jeito, para limpeza.

Devo capturar Exception para ficar seguro?

Não. Um except: vazio ou except Exception: esconde bugs que você não antecipou. Capture a exceção específica da qual você sabe se recuperar, e deixe todo o resto propagar para você ver o problema real.

Qual a diferença entre raise e raise from?

raise NewError(...) lança uma nova exceção. raise NewError(...) from original mantém a exceção original anexada como causa, o que o Python mostra no traceback. Use from quando um erro de baixo nível dispara um de alto nível que você quer expor.

Aprenda a programar com o Coddy

COMEÇAR