image

Access unlimited bootcamps and 650+ courses forever

60
%OFF
Article image
Fernanda Araujo
Fernanda Araujo18/06/2025 09:19
Share
WEX - End to End EngineeringRecommended for youWEX - End to End Engineering

Paradigmas de Linguagens de Programação em Python: Python Estruturado (Part. 05)

  • #Python

O paradigma estruturado se baseia em três pilares principais: sequência, decisão e repetição. Quando escrevemos código com foco nessa abordagem, valorizamos a clareza, a lógica linear e o controle explícito do fluxo de execução.

Neste artigo, vamos explorar o tratamento de exceções e eventos, parte essencial do paradigma estruturado, especialmente quando lidamos com erros que podem interromper o programa. Você verá como capturar e manipular erros usando try, except, e outras estruturas da linguagem Python.

⚠️ O que são erros e exceções?

Em Python, os erros podem ser classificados em dois grandes grupos:

  • Erros de sintaxe: são detectados antes da execução do programa.
  • Exceções: são erros detectados durante a execução.

Vamos a um exemplo simples de exceção:

python

# Exemplo 1 - Erro em tempo de execução
numero = int(input("Digite um número: "))
print(10 / numero)  # Tente digitar 0

Se o usuário digitar 0, o programa lança uma exceção do tipo ZeroDivisionError. Vamos aprender a tratar esse tipo de erro.

🛡️ Bloco try e except

Para evitar que o programa quebre, usamos o bloco try/except:

python

# Exemplo 2 - Tratamento básico com try e except
try:
  numero = int(input("Digite um número: "))
  resultado = 10 / numero
  print("Resultado:", resultado)
except ZeroDivisionError:
  print("Erro: divisão por zero não é permitida.")

Agora o programa não interrompe sua execução e trata o erro de forma controlada.

🧠 Captura de múltiplas exceções

Podemos capturar vários tipos de erro no mesmo bloco:

python

# Exemplo 3 - Capturando múltiplas exceções
try:
  numero = int(input("Digite um número: "))
  resultado = 10 / numero
  print("Resultado:", resultado)
except ZeroDivisionError:
  print("Erro: divisão por zero.")
except ValueError:
  print("Erro: valor inválido. Digite apenas números.")

Esse tipo de estrutura ajuda a manter o controle sobre diferentes cenários de erro.

🔄 Estrutura completa: try, except, else, finally

O Python também permite tratar erros com mais detalhes, usando else e finally:

python

# Exemplo 4 - Estrutura completa
try:
  numero = int(input("Digite um número: "))
  resultado = 10 / numero
except ZeroDivisionError:
  print("Erro: divisão por zero.")
except ValueError:
  print("Erro: entrada inválida.")
else:
  print("Resultado:", resultado)
finally:
  print("Encerrando o programa.")
  • else é executado se não houve exceção.
  • finally sempre é executado, ocorrendo ou não erro.

🎯 Exceções personalizadas e uso com funções

Também é possível criar exceções personalizadas para deixar o código mais claro e modular:

python

# Exemplo 5 - Criando uma exceção personalizada
def sacar(valor):
  if valor < 0:
      raise ValueError("O valor do saque não pode ser negativo.")
  print(f"Saque de R${valor} realizado com sucesso.")

try:
  sacar(-100)
except ValueError as erro:
  print("Erro ao sacar:", erro)

Esse padrão é muito usado em aplicações reais, principalmente quando trabalhamos com validações.

🧰 Tratamento de eventos na prática

Embora Python não tenha um sistema de eventos como em linguagens voltadas a interfaces gráficas, podemos simular tratamento de eventos com funções e exceções, especialmente em sistemas com lógica baseada em ações:

python

# Exemplo bônus - Simulando evento de clique
def ao_clicar():
  print("Botão clicado! Iniciando ação...")

try:
  evento = input("Digite 'clicar' para simular o clique: ")
  if evento != "clicar":
      raise Exception("Evento inválido.")
  ao_clicar()
except Exception as e:
  print("Erro de evento:", e)

🔁 Uso de loops com tratamento de exceções

Mostra como a estrutura repetitiva (while/for) se combina com tratamento de erros para criar fluxos mais seguros:

python

# Exemplo extra - Validação contínua com while e try
while True:
  try:
      idade = int(input("Digite sua idade: "))
      if idade < 0:
          raise ValueError("Idade não pode ser negativa.")
      break
  except ValueError as e:
      print("Erro:", e)

print("Idade registrada com sucesso:", idade)

🟢 Por que incluir?

Mostra um caso de uso real com repetição e validação — muito usado em sistemas de cadastro e formulários.

🧪 Demonstração de traceback para debugging

Apresenta a biblioteca traceback que imprime o erro completo — muito útil para depuração.

python

import traceback

try:
  resultado = 1 / 0
except Exception:
  print("Ocorreu um erro:")
  traceback.print_exc()

🟢 Por que incluir?

Mostra ao leitor como rastrear exatamente onde o erro ocorreu — isso ensina boas práticas de depuração.

🧰 Importação de funções/módulos com try/except

Você pode ilustrar como proteger importações externas com exceções:

python

try:
  import numpy as np
except ImportError:
  print("Biblioteca numpy não está instalada.")

🟢 Por que incluir?

Aborda um item que você mencionou: uso de pacotes externos com segurança.

🧱 Organização em funções + exceções

Você pode mostrar como organizar tudo isso dentro de funções reutilizáveis, mantendo o código estruturado:

python

def dividir(a, b):
  try:
      return a / b
  except ZeroDivisionError:
      return "Divisão por zero não permitida"

print(dividir(10, 0))

🟢 Por que incluir?

Conecta exceções com modularização, um conceito central do paradigma estruturado.

🚨 Tabela de exceções comuns

Você pode colocar uma tabela-resumo com os erros mais frequentes em Python, como um guia rápido:

image

🟢 Por que incluir?

Ajuda o leitor a memorizar os nomes e situações em que essas exceções acontecem.

📝 Contextualização em sistemas reais: logging e monitoramento de erros

  • Em projetos profissionais, não basta só capturar a exceção e mostrar mensagem no console. Usa-se logging para registrar erros em arquivos ou sistemas de monitoramento.
python

import logging

logging.basicConfig(filename='app.log', level=logging.ERROR,
                  format='%(asctime)s - %(levelname)s - %(message)s')

try:
  x = 1 / 0
except ZeroDivisionError as e:
  logging.error("Erro na divisão", exc_info=True)

💡 Explique a importância do logging para auditoria e manutenção.

🔄 Re-raising e tratamento seletivo de exceções

  • Mostrar como relançar exceções para não esconder erros importantes:
python

try:
  ...
except ValueError as e:
  # Tratar localmente
  print("Erro de valor:", e)
  # Re-raise para tratamento superior ou log externo
  raise

🛠️ Context Managers para controle de recursos

  • Use a construção with para garantir fechamento de arquivos, conexões, e mostrar como ele funciona por baixo dos panos com métodos __enter__ e __exit__, que também tratam exceções.
python

with open('arquivo.txt') as f:
  conteudo = f.read()
  • Explique o paralelo com o paradigma estruturado: controle rígido de abertura e fechamento de recursos.

🏗️ Custom Exception Hierarchy

  • Mostre como criar uma hierarquia de exceções para projetos maiores, facilitando o tratamento e a organização do código.
python

class ErroAplicacao(Exception):
  pass

class ErroValidacao(ErroAplicacao):
  pass

class ErroConexao(ErroAplicacao):
  pass

try:
  raise ErroValidacao("Dados inválidos")
except ErroAplicacao as e:
  print("Erro na aplicação:", e)

✅ Testes automatizados para validação de tratamento de exceções

  • Explique a importância de testes unitários para garantir que o tratamento de exceções funciona. Mostre exemplo com pytest:
python

import pytest

def dividir(a, b):
  if b == 0:
      raise ZeroDivisionError("Divisão por zero")
  return a / b

def test_dividir_zero():
  with pytest.raises(ZeroDivisionError):
      dividir(10, 0)

⚡ Performance e overhead do tratamento de exceções

O que é overhead em exceções?

Overhead significa o custo extra — tempo e recursos computacionais adicionais — que a execução de uma operação exige.

No caso das exceções em Python, lançar e capturar uma exceção não é tão barato quanto uma simples instrução condicional (como um if). Internamente, o mecanismo de exceções envolve:

  • Interrupção do fluxo normal do programa.
  • Construção do objeto de exceção.
  • Busca da estrutura de tratamento adequada (try/except).
  • Possível unwind da pilha de chamadas para encontrar o handler correto.
  • Execução do código no bloco except.

Esse processo consome mais recursos do que apenas avaliar uma condição.

Quando usar exceções é custoso?

Exceções são para situações excepcionais, ou seja, casos que não deveriam ocorrer na execução normal do programa.

Se você usa exceções como parte normal do fluxo de controle — por exemplo, para validar dados que são esperados frequentemente inválidos — isso pode:

  • Tornar o código menos performático, porque o custo de levantar exceções se acumula.
  • Tornar o código mais difícil de entender, já que o fluxo fica mais difícil de seguir.

Exemplo comparativo: validação com if vs exceção

python

# Validação preventiva com if (mais eficiente)
def dividir(a, b):
  if b == 0:
      return None  # ou um valor especial, ou lançar exceção depois
  return a / b

# Uso
resultado = dividir(10, 0)
if resultado is None:
  print("Divisão por zero detectada antes de executar.")
else:
  print(resultado)

vs

python

# Uso direto de exceção (mais custoso se acionada frequentemente)
def dividir(a, b):
  return a / b

try:
  print(dividir(10, 0))
except ZeroDivisionError:
  print("Erro: divisão por zero")

Recomendações práticas

  • Use validações condicionais (if) para casos comuns ou esperados (ex: checar se lista está vazia, se divisor é zero, etc).
  • Use exceções para casos inesperados ou erros que não deveriam acontecer na lógica normal (ex: falha de conexão, arquivo inexistente, etc).
  • Em código crítico de performance, evite usar exceções em loops ou chamadas muito frequentes.
  • Para debugar e lidar com erros que realmente interrompem o programa, use exceções com logging e monitoração.

Por que isso importa?

Quando você programa para sistemas grandes, como servidores web, sistemas financeiros ou jogos, otimizar o fluxo de controle faz diferença no tempo de resposta e uso de recursos.

Usar exceções corretamente evita gargalos e mantém seu código:

  • Clareza (fluxo fácil de entender)
  • Robustez (tratamento eficaz de erros)
  • Performance (evita custos desnecessários)

🌐 Integração com sistemas externos (exemplo com APIs REST)

  • Demonstre tratamento de exceções em chamadas a APIs com bibliotecas como requests, tratando erros de conexão, timeout, etc.
python

import requests

try:
  response = requests.get('https://api.exemplo.com/dados', timeout=5)
  response.raise_for_status()
except requests.exceptions.Timeout:
  print("Timeout na requisição")
except requests.exceptions.HTTPError as e:
  print("Erro HTTP:", e)
except requests.exceptions.RequestException as e:
  print("Erro na requisição:", e)

🔚 Conclusão

Neste artigo, exploramos o paradigma estruturado de programação em Python com foco no tratamento de erros e exceções. Compreendemos como lidar com eventos inesperados de forma segura e organizada, utilizando estruturas como try, except, else e finally, além de criar exceções personalizadas que tornam o código mais legível e fácil de manter.

Mais do que capturar erros, vimos que o verdadeiro valor está em prevenir falhas silenciosas, registrar problemas de forma adequada com logging, e manter o fluxo lógico do programa mesmo diante de situações adversas. Esse tipo de abordagem é fundamental em aplicações reais, especialmente quando lidamos com entrada de dados do usuário, arquivos ou integração com sistemas externos.

Para aplicar tudo que foi estudado na prática, desenvolvi um projeto completo e funcional no GitHub que implementa todos os tópicos abordados aqui, incluindo testes automatizados com pytest, logging, estrutura de diretórios e exceções customizadas.

🌐 Projeto open source disponível para estudo e colaboração

Você pode acessar, estudar e reutilizar o projeto como base para seus próprios estudos ou aplicações:

🔗 Acesse o projeto no GitHub: Tratamento Estruturado de Erros em Python

image

Share
Recommended for you
Suzano - Python Developer
BairesDev - Machine Learning Practitioner
Santander - Cibersegurança #2
Comments (1)
Sisnando Junior
Sisnando Junior - 18/06/2025 09:50

Excelente artigo!

Recommended for youWEX - End to End Engineering