Dê o salto de scripts soltos para software estruturado: encapsule lógica em funções e módulos, modele entidades com classes e herança, persista dados com pathlib e json, trate falhas e valide tudo com pytest.
Ouça o episódio complementar de Garlucas direto por aqui antes ou depois das oficinas para conectar modularização com funções/classes, persistência segura com pathlib e json, e testes automatizados com pytest.
Código sustentável separa responsabilidades em módulos, protege operações de disco com exceções e garante comportamento com pytest.
OFICINA 01 · CAPÍTULO 8
Funções, Parâmetros Flexíveis e Módulos
Funções dão nome a blocos reutilizáveis e evitam duplicação. Ao receber coleções, lembre que listas são passadas por referência: se quiser preservar a lista original, passe uma cópia com funcao(lista[:]).
Argumentos posicionais, nomeados e padrões: use def perfil(nome, cargo='suporte'): para tornar chamadas legíveis.
*args e **kwargs:*args empacota múltiplos argumentos posicionais em uma tupla; **kwargs empacota pares chave-valor arbitrários em um dicionário.
Módulos: salve funções auxiliares em utils.py e importe apenas o necessário (from utils import formatar_registro as fmt).
OFICINA 02 · CAPÍTULO 9
Programação Orientada a Objetos: Classes e Herança
Classes modelam entidades do mundo real unindo dados (atributos) e comportamentos (métodos):
__init__(self, ...): método construtor executado automaticamente ao instanciar a classe; o self dá acesso aos atributos daquela instância.
Herança & super(): uma classe filha herda atributos e métodos da classe pai (ex.: ElectricCar(Car)), chamando super().__init__(...) e podendo sobrescrever métodos específicos.
Composição: quando um detalhe cresce demais (ex.: Battery), extraia-o para uma classe separada e use-a como atributo dentro de ElectricCar.
OFICINA 03 · CAPÍTULO 10
Arquivos Modernos com pathlib
Na 3ª edição de Python Crash Course, Eric Matthes adota a biblioteca padrão pathlib no lugar de chamadas antigas com open() manual — funcionando de forma consistente no Windows, macOS e Linux:
Python · Ler e escrever texto com pathlib.Path
from pathlib import Path
caminho = Path('dados/notas.txt')
caminho.parent.mkdir(parents=True, exist_ok=True)
caminho.write_text('Linha 1\nLinha 2\n', encoding='utf-8')
conteudo = caminho.read_text(encoding='utf-8').rstrip()
for linha in conteudo.splitlines():
print(linha)
OFICINA 04 · CAPÍTULO 10
Tratamento de Exceções & Persistência em JSON
Programas profissionais não travam com um traceback feio quando falta um arquivo ou o usuário digita zero. Use try / except / else para tratar erros específicos (nunca except: genérico sem motivo) e o módulo json para salvar listas e dicionários entre execuções:
Python · Carregar JSON com fallback seguro via try-except
from pathlib import Path
import json
def carregar_perfil(arquivo='perfil.json'):
path = Path(arquivo)
if not path.exists():
return None
try:
dados = path.read_text(encoding='utf-8')
return json.loads(dados)
except json.JSONDecodeError:
return None
OFICINA 05 · CAPÍTULO 11
Testes Automatizados com pytest
A 3ª edição substitui unittest pelo pytest, padrão de mercado pela simplicidade. Basta criar arquivos começando com test_*.py, funções começando com test_*() e usar assert direto:
Asserções mais usadas no pytest (Tabela 11-1 do livro)
Asserção
O Que Verifica
assert a == b / assert a != b
Igualdade ou diferença exata entre dois valores.
assert x / assert not x
Avaliação booleana verdadeira ou falsa.
assert item in lista
Presença (ou ausência com not in) em uma coleção.
@pytest.fixture
Prepara instâncias reutilizáveis (ex.: um objeto de classe) antes de vários testes.
OFICINA 06 · LABORATÓRIO INTEGRADO
Lab: Testando Classe + Persistência com pytest
Veja como unir tudo em um arquivo test_conta.py e rodar no terminal:
Python · test_conta.py com @pytest.fixture
import pytest
class Conta:
def __init__(self, titular, saldo=0.0):
self.titular = titular
self.saldo = saldo
def depositar(self, valor):
if valor <= 0:
raise ValueError('Valor deve ser positivo')
self.saldo += valor
@pytest.fixture
def conta_padrao():
return Conta('Lucas', 100.0)
def test_deposito_valido(conta_padrao):
conta_padrao.depositar(50.0)
assert conta_padrao.saldo == 150.0
def test_deposito_invalido(conta_padrao):
with pytest.raises(ValueError):
conta_padrao.depositar(-10.0)
LABORATÓRIO INTERATIVO · CAPÍTULOS 8–11
Simulador de Arquitetura & Qualidade Python
Avalie o nível de maturidade de um script conforme modularização, tratamento de disco e cobertura com pytest.
Maturidade do Projeto
Software Estruturado
Resiliência a Falhas
Alta (Erros Tratados)
Segurança para Refatorar
Garantida via pytest
Excelente transição do script para software real: módulos claros facilitam manutenção, pathlib + try/except protegem dados e o pytest garante refatorações sem medo.
VERIFICAÇÃO DE DOMÍNIO · 4 QUESTÕES
Teste Rápido da Etapa 3
Valide os conceitos dos Capítulos 8 a 11 antes de seguir para o projeto Pygame.
1. Como passar uma lista para uma função em Python garantindo que a lista original não seja modificada?
2. Qual é a função de super().__init__(...) dentro de uma classe filha em Python?
3. Qual vantagem o uso de pathlib.Path traz em comparação a concatenar caminhos de arquivo manualmente com barras?
4. Para que serve o decorador @pytest.fixture no Capítulo 11?
CONCLUSÃO DA ETAPA 3
Checklist de Prontidão & Exportação
Marque cada marco concluído; seu progresso fica salvo no navegador.
PRÓXIMA PARADA · ETAPA 4 DE 5
Projeto de Consolidação Lógica
Aplique classes, módulos e arquitetura orientada a objetos construindo o jogo Alien Invasion completo com Pygame nos Capítulos 12 a 14.