🌗 ← Índice
Data: 05/07/2026
Nível: Básico → Intermediário
Tu já viu teu código explodir com NameError, TypeError ou FileNotFoundError. Hoje tu vai aprender a dominar o caos — prever falhas, tratá-las com elegância e até criar teus próprios erros.
Python é uma linguagem dinâmica e interpretada. Erros só aparecem em tempo de execução — não tem compilador pra te salvar.
# Isso roda até chegar na bomba:
print("Tudo certo")
x = 1 / 0 # ZeroDivisionError — crash!
print("Nunca vou rodar")
Solução: envolver código arriscado com try/except.
try:
numero = int(input("Digite um número: "))
print(f"100 / {numero} = {100 / numero}")
except ValueError:
print("Isso não é um número, animal.")
except ZeroDivisionError:
print("Dividir por zero não rola.")
O Python tenta o bloco try. Se der ValueError, cai no primeiro except. Se der ZeroDivisionError, cai no segundo.
except (ValueError, ZeroDivisionError) as e:
print(f"Deu ruim: {e}")
except FileNotFoundError as e:
print(f"Arquivo '{e.filename}' não encontrado.")
try:
arquivo = open("dados.txt")
except FileNotFoundError:
print("Arquivo não existe, criando...")
arquivo = open("dados.txt", "w")
else:
# Só chega aqui se open() funcionou
conteudo = arquivo.read()
print(f"Li {len(conteudo)} caracteres")
Regra: else roda se (e somente se) o try não lançou exceção.
conexao = None
try:
conexao = conectar_banco()
dados = conexao.buscar("clientes")
except DatabaseError:
print("Falha na consulta")
finally:
if conexao:
conexao.fechar() # SEMPRE fecha, mesmo com erro
print("Recursos liberados")
finally é ideal pra limpar recursos: fechar arquivos, conexões, liberar locks.
def sacar(saldo, valor):
if valor > saldo:
raise ValueError(f"Saldo insuficiente: R${saldo} < R${valor}")
return saldo - valor
try:
novo_saldo = sacar(100, 200)
except ValueError as e:
print(e) # "Saldo insuficiente: R$100 < R$200"
class SaldoInsuficienteError(Exception):
"""Lançada quando tenta sacar mais do que tem."""
def __init__(self, saldo, valor):
self.saldo = saldo
self.valor = valor
super().__init__(f"Saldo R${saldo} < saque R${valor}")
def sacar(saldo, valor):
if valor > saldo:
raise SaldoInsuficienteError(saldo, valor)
return saldo - valor
Agora quem chamar sacar() pode capturar especificamente teu erro:
try:
sacar(100, 200)
except SaldoInsuficienteError as e:
print(f"Faltou R${e.valor - e.saldo}")
try:
fazer_algo_arriscado()
except: # ❌ PÉSSIMO — captura TUDO (até Ctrl+C!)
pass # ❌ Silencia o erro — impossível debugar
Sempre especifique o tipo de exceção:
try:
fazer_algo_arriscado()
except ValueError: # ✅ Captura só o que interessa
tratar_erro()
| Exceção | Causa |
|---|
|---|---|
| `ValueError` | Tipo certo, valor inválido (ex: `int("abc")`) |
|---|---|
| `TypeError` | Operação em tipo errado (ex: `"a" + 5`) |
| `FileNotFoundError` | Arquivo não existe |
| `KeyError` | Chave inexistente no dicionário |
| `IndexError` | Índice fora da lista |
| `ZeroDivisionError` | Divisão por zero |
| `ImportError` | Módulo não encontrado |
| `AttributeError` | Objeto não tem o atributo/método |
Crie uma função dividir(a, b) que retorna a / b, mas se b for zero, retorna None e imprime "Divisão por zero".
# Teu código aqui
Escreva um código que tenta abrir config.json. Se não existir, cria ele com {} vazio.
# Teu código aqui
Crie uma função validar_idade(idade) que:
# Teu código aqui
Crie uma mini-calculadora que:
1. Pede dois números e uma operação (+, -, *, /)
2. Trata ValueError se o usuário digitar texto
3. Trata ZeroDivisionError na divisão
4. Trata operação inválida com raise próprio
5. Usa finally pra dar tchau
6. Pergunta se quer continuar (loop com while)
# Teu código aqui — sem olhar o gabarito!
def dividir(a, b):
try:
return a / b
except ZeroDivisionError:
print("Divisão por zero")
return None
print(dividir(10, 2)) # 5.0
print(dividir(10, 0)) # Divisão por zero \n None
import json
try:
with open("config.json") as f:
config = json.load(f)
except FileNotFoundError:
config = {}
with open("config.json", "w") as f:
json.dump(config, f)
print("config.json criado com {}")
print(config)
def validar_idade(idade):
if idade < 0:
raise ValueError("Idade não pode ser negativa")
if idade > 150:
raise ValueError("Idade suspeita (>150 anos)")
return True
# Teste
try:
validar_idade(-5)
except ValueError as e:
print(e)
class OperacaoInvalidaError(Exception):
pass
while True:
try:
a = float(input("Número 1: "))
b = float(input("Número 2: "))
op = input("Operação (+ - * /): ")
if op == "+":
resultado = a + b
elif op == "-":
resultado = a - b
elif op == "*":
resultado = a * b
elif op == "/":
resultado = a / b
else:
raise OperacaoInvalidaError(f"Operação '{op}' não existe")
print(f"→ {a} {op} {b} = {resultado}")
except ValueError:
print("Digite um número válido!")
except ZeroDivisionError:
print("Não pode dividir por zero!")
except OperacaoInvalidaError as e:
print(e)
finally:
continuar = input("\nContinuar? (s/n): ").lower()
if continuar != "s":
print("Valeu, falou!")
break
**Próxima aula:** P08 — Módulos e Pacotes (import, venv, pip, `__name__`)