Módulo 12 - Exceções, logging e robustez

else, finally e o estilo EAFP

10 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

O que você vai aprender

  • Usar a cláusula else para o código que só roda se não houve erro.
  • Usar finally para limpeza que sempre acontece.
  • Comparar os estilos EAFP e LBYL com clareza.
  • Escolher o estilo certo para cada situação.

As cláusulas else e finally

O bloco try tem quatro cláusulas, e a maioria das pessoas só usa duas. A cláusula else roda apenas se o try terminou sem levantar exceção. Ela serve para separar, com clareza, o código que pode falhar do código que só deve rodar em caso de sucesso. Sem o else, você seria tentado a colocar tudo dentro do try, o que aumenta a chance de capturar por engano um erro vindo do código de sucesso. O else mantém o try enxuto, contendo só a linha que de fato pode falhar.

def carregar(caminho):
    try:
        arquivo = open(caminho, encoding="utf-8")
    except FileNotFoundError:
        print("arquivo nao encontrado")
        return None
    else:
        # So roda se o open deu certo: leitura fica fora do try.
        conteudo = arquivo.read()
        return conteudo
    finally:
        # Roda sempre, deu certo ou nao. Aqui so avisa;
        # com o open acima, o with seria ainda melhor.
        print("tentativa de carga concluida")

else contém o código de sucesso; finally roda em qualquer caso.

A cláusula finally é a companheira do else e roda sempre, tenha havido erro ou não, inclusive se a função retornar no meio do try. É o lugar para liberação de recursos e limpeza: fechar arquivos, soltar conexões, restaurar estado. No exemplo, o finally apenas avisa, mas em código real ele garante que a limpeza aconteça mesmo quando algo falha. Vale lembrar que, para arquivos, o with que você viu no módulo de context managers já cuida disso de forma mais elegante que um try/finally manual.

EAFP contra LBYL

Existem dois estilos de lidar com o que pode dar errado, e Python tem uma preferência clara. O LBYL, olhe antes de saltar, verifica todas as condições antes de agir: será que a chave existe, será que o arquivo está lá, será que o número é válido. O EAFP, mais fácil pedir perdão que permissão, faz o contrário: tenta a operação e trata a exceção se ela ocorrer. O estilo pythônico é o EAFP, e não é só gosto. Ele evita duplicar a lógica de checagem e escapa de uma armadilha real, as condições de corrida.

LBYL (checar antes)

  • if chave in dicionario: use dicionario[chave]
  • Duplica a lógica: checa e depois acessa
  • Entre o if e o uso, o estado pode mudar
  • Comum em Java, C e afins

EAFP (tentar e tratar)

  • try: use dicionario[chave] except KeyError: trate
  • Uma tentativa só, sem checagem redundante
  • Sem janela para corrida entre checar e agir
  • Idiomático e recomendado em Python
dados = {"nome": "Ana", "idade": 30}

# LBYL: checa antes de acessar
if "email" in dados:
    email = dados["email"]
else:
    email = "sem email"

# EAFP: tenta e trata (mais pythonico)
try:
    email = dados["email"]
except KeyError:
    email = "sem email"

# E, para este caso especifico, o mais curto de todos:
email = dados.get("email", "sem email")

O mesmo objetivo em LBYL, EAFP e com o método get, do mais verboso ao mais direto.

Escolhendo o estilo certo

EAFP é o padrão em Python, mas não é uma lei absoluta. Ele brilha quando a falha é rara: tentar a operação, que quase sempre dá certo, sai mais barato e mais limpo do que checar toda vez. Também é a escolha certa quando entre a checagem e a ação o estado pode mudar, como ao mexer com arquivos ou recursos compartilhados, pois evita a condição de corrida em que o if aprova e o mundo muda antes da linha seguinte. E é mais legível quando a checagem antecipada duplicaria a lógica da própria operação.

Há casos, porém, em que LBYL ganha. Se a falha é esperada e frequente, e levantar exceções o tempo todo custaria caro, uma checagem prévia simples pode ser mais eficiente e clara. E validação de entrada, que o próximo tema aprofunda, muitas vezes é um if bem colocado no começo da função. A regra mental é: prefira EAFP por padrão, especialmente com recursos e dicionários; use LBYL quando a checagem for barata, a falha for comum ou a validação precisar acontecer bem no início.

Teste rápido

Por que o estilo EAFP costuma ser preferido a LBYL em Python?

Perguntas frequentes

Qual a diferença entre colocar código no else e no fim do try?
Código no else só roda se o try não levantou exceção, e um erro nele não é capturado pelos except daquele try. Colocá-lo dentro do try aumentaria o risco de um except pegar por engano um erro do código de sucesso. O else deixa a intenção clara e o try enxuto.
O finally roda mesmo se eu der return dentro do try?
Sim. O finally roda sempre antes de a função de fato retornar, mesmo que haja return, break ou uma exceção no try ou no except. Por isso ele é o lugar certo para liberar recursos e garantir limpeza, aconteça o que acontecer no bloco.
EAFP não deixa o código mais lento por causa das exceções?
Levantar uma exceção tem custo, mas o caminho de sucesso do try é muito barato. Quando a falha é rara, EAFP costuma ser mais rápido que checar toda vez. Só quando as falhas são frequentes o custo das exceções pesa, e aí LBYL pode compensar. Meça se for crítico.
O que é uma condição de corrida no contexto de LBYL?
É quando o estado muda entre a checagem e a ação. Por exemplo, você verifica que um arquivo existe e, no instante seguinte, ele é apagado por outro processo antes de você abri-lo. EAFP evita isso ao tentar a operação diretamente e tratar a falha se ela ocorrer.
Para pegar um valor de dicionário, uso try ou get?
Para um valor com padrão, dicionario.get(chave, padrao) é o mais direto e legível. O try/except KeyError brilha quando a ausência da chave exige uma reação mais elaborada que apenas um valor padrão. Ambos seguem o espírito EAFP de não checar antes desnecessariamente.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.