Exceções em Python: O Guia Básico de Try e Except

Um carro azul onde como placa temos o ícone de progração do python. O pneu frontal da direita do carro está furado. Na frente do carro temos o pneu step com uma tag dizendo 'Plano B'.

Exceções são avisos de que algo deu errado no seu código, como tentar dividir por zero. Em Python, usamos o bloco try e except para “pegar” e tratar esses problemas, evitando que o programa pare de repente. Também podemos criar e levantar nossas próprias exceções para dar mensagens claras.

Introdução: Por que o “Plano B” é crucial?

No dia a dia de qualquer desenvolvedor, um fato é inevitável: as coisas dão errado. Não importa o quão bom seja seu código, sempre há a chance de um imprevisto acontecer, como um arquivo que não existe, uma conexão que cai ou um usuário digitando texto onde deveria ser um número. É aqui que entram as exceções.

As exceções não são “bugs” (erros de lógica), mas sim eventos que interrompem o fluxo normal do seu programa. Pense nisso como um GPS: se você planejou ir pela rua X, mas ela está interditada (a exceção), o GPS não deve travar; ele deve te dar uma rota alternativa (o tratamento da exceção). Em Python, aprender a lidar com exceções corretamente – ou seja, tratá-las – é o que separa um programa que “quebra” de um que é robusto. Neste post, vamos entender como interpretar, tratar e até criar nossas próprias exceções em Python.

🧐 Interpretando Exceções: O Detetive do Código

Quando o Python encontra um problema e não sabe o que fazer, ele levanta uma exceção (ou raise). Você já deve ter visto algo parecido:

Traceback (most recent call last):
  File "meu_programa.py", line 5, in <module>
    resultado = 10 / 0
ZeroDivisionError: division by zero

A chave é saber ler o Traceback (o rastro que a exceção deixou):

  1. Traceback: Indica que algo falhou.
  2. File "meu_programa.py", line 5: Mostra exatamente onde o erro aconteceu (arquivo e linha).
  3. ZeroDivisionError: O nome da exceção. Este é o tipo de problema. No nosso caso, é uma tentativa de divisão por zero (ZeroDivisionError).
  4. division by zero: A mensagem detalhada do problema.

Entender esses nomes (TypeError, FileNotFoundError, ValueError, etc.) é o primeiro passo para resolver o problema, pois eles te dizem a natureza da falha.

🛡️ Tratando Exceções: O Poder do try e except

Tratar uma exceção é dar um “Plano B” para o Python. É como dizer: “Tente fazer isso (try), mas se der o erro X, faça isso outro (except)”.

A sintaxe é bastante intuitiva:

def pegar_numero():
    while True:
        try:
            # 1. Tenta executar este bloco
            entrada = input("Digite um número: ")
            numero = int(entrada)
            break
        except ValueError:
            # 2. SE der ValueError, executa este bloco
            print("Isso não parece um número inteiro. Tente de novo!")
        except Exception as e:
            # 3. Bloco mais genérico para outros erros
            print(f"Ocorreu um erro inesperado: {e}")
            break
    return numero

No exemplo acima, se o usuário digitar “abc”, o Python não consegue converter para inteiro e levanta um ValueError. O bloco except ValueError: “pega” essa exceção, exibe a mensagem amigável e o programa continua rodando, em vez de travar.

🔨 Exemplo Prático: Calculadora Anti-Quebra

Vamos simular uma pequena calculadora que aceita uma operação, mas que não pode quebrar ao dividir por zero.

def dividir(a, b):
    """
    Tenta dividir dois números e trata a exceção ZeroDivisionError.
    """
    try:
        # Tenta fazer a divisão
        resultado = a / b
        print(f"Resultado da divisão: {resultado}")
    except ZeroDivisionError:
        # Se for divisão por zero, exibe uma mensagem de alerta
        print("🚨 Opa! Não é possível dividir por zero. A operação foi cancelada.")
        resultado = None
    except TypeError:
        # Se algum dos valores não for número (ex: 5 / 'a')
        print("🚫 Erro de tipo. Certifique-se de que os valores são números.")
        resultado = None
    finally:
        # Este bloco sempre será executado, dando erro ou não.
        print("Divisão finalizada. Tentativa de cálculo concluída.")
        
# Testes
dividir(10, 2)
dividir(10, 0)
dividir(10, "a")

✋ Lançando Suas Próprias Exceções (raise)

Às vezes, seu código precisa forçar uma parada ou um aviso, mesmo que o Python não tenha detectado um erro técnico. É como quando o motorista do ônibus vê um buraco na pista (que não é um erro mecânico, mas um perigo) e precisa parar o veículo.

Usamos a palavra-chave raise para levantar uma exceção. Isso é super útil para validação de dados.

def sacar(saldo, valor):
    if valor <= 0:
        # Levantamos um erro que faz sentido para a nossa regra de negócio
        raise ValueError("O valor de saque deve ser positivo e maior que zero.")
    if valor > saldo:
        # Levantamos outro erro
        raise RuntimeError("Saldo insuficiente para realizar esta operação.")
        
    saldo -= valor
    return saldo

# Exemplo de uso
try:
    novo_saldo = sacar(500, 600)
    print(f"Novo saldo: {novo_saldo}")
except ValueError as e:
    print(f"Erro na validação do valor: {e}")
except RuntimeError as e:
    print(f"Erro na operação: {e}")

❌ Erros Comuns / Armadilhas

  1. except vazio: Usar apenas except: sem especificar a exceção. Isso pega qualquer erro, incluindo erros de digitação (bugs), mascarando problemas reais. Sempre tente especificar a exceção, como except ValueError.
  2. Exceções genéricas demais: Tratar Exception no primeiro except. Se você faz isso, exceções mais específicas, como ZeroDivisionError, nunca serão alcançadas. Coloque o except Exception por último.
  3. Ignorar a exceção: Não fazer nada no bloco except (apenas pass). O programa não quebra, mas você perdeu a informação importante de que algo deu errado. Sempre logue ou informe o erro de alguma forma.

✅ Boas Práticas / Dicas Rápidas

  • Seja específico: Trate as exceções mais específicas primeiro (ZeroDivisionError) e as genéricas por último (Exception).
  • Use finally para limpeza: Use o bloco finally para garantir que recursos críticos (como fechar um arquivo ou uma conexão de banco de dados) sejam liberados, independente de ter ocorrido um erro ou não.
  • Evite o try/except em excesso: Não trate exceções onde você pode usar validações simples (if/else). O try/except é para eventos inesperados, não para checagens de rotina.
  • Logue o erro: Em produção, em vez de apenas print(), use um módulo de logging para registrar o erro, facilitando a depuração posterior.

Conclusão

Dominar o tratamento de exceções em Python com try, except e raise é como colocar airbags e freios ABS no seu código. Garante que, mesmo no trânsito pesado de dados e imprevistos, seu programa continue seguro e forneça uma experiência suave para o usuário.

Lembre-se: um código robusto não é aquele que nunca tem erros, mas sim aquele que sabe lidar com eles. Se você quer se aprofundar ainda mais no mundo do Python, não deixe de conferir o livro Curso Intensivo de Python: uma Introdução Prática e Baseada em Projetos à Programação. Lá você vai aprender na prática como utilizar o python para resolver problemas reais!

Compre aqui “Curso Intensivo de Python: uma Introdução Prática e Baseada em Projetos à Programação”

Rolar para cima