Melhores Práticas de Iteradores e Decorators
Diretrizes para iteração preguiçosa, higiene de decorators e pipelines composáveis - os padrões que mantêm os serviços Python seguros em memória e depuráveis.
Como Usar Esta Lista
- Revise ao construir pipelines ETL ou processadores de logs.
- Aplique em frameworks com muitos decorators (autenticação, retentativa, métricas).
- Combine com profiling quando as cadeias de iteradores ficarem profundas.
- Use em revisão de código para
lambdaem loops e@wrapsausentes.
A - Iteração
- Use geradores ou expressões geradoras para streams maiores que a memória. Materialize apenas no consumidor final quando necessário.
- Componha pipelines como pequenas funções geradoras. Cada estágio faz uma transformação - testes mais fáceis.
- Prefira
itertoolsparachain,islice,groupby,product. Testados em batalha e preguiçosos. - Ordene antes de
groupbyquando agrupar por chave. O requisito de chave consecutiva é fácil de esquecer. - Documente iteradores de passagem única. Chamadores não devem assumir repetição sem
teeoulist().
B - Geradores e Recursos
- Use
try/finallyou@contextmanagerdentro de geradores que detêm arquivos/sockets. Consumidores podem parar cedo. - Feche geradores com
.close()em testes quando a limpeza for importante. DisparaGeneratorExitnoyield. - Evite efeitos colaterais na definição do gerador - efeitos são executados no consumo. Semântica preguiçosa surpreende novatos.
- Use
yield fromem vez de loopsfor/yieldmanuais. Delegação e propagação de retorno mais claras. - Limite iteradores infinitos com
isliceou condições debreak.count()ecycle()nunca param sozinhos.
C - Decorators
- Sempre aplique
@functools.wrapsem funções wrapper. Preserva__name__, documentação e anotações. - Mantenha pilhas de decorators rasas e ordenadas consistentemente. Documente a ordem de
classmethod/staticmethod. - Parametrize via fábricas de decorators (
def retry(n):). Evite configuração mutável global em decorators. - Não engula exceções, a menos que o propósito do decorator seja supressão. Re-lance ou encadeie com
from. - Prefira middleware/Depends do FastAPI para escopo de requisição. Decorators de função para utilitários puros.
D - functools e Caching
- Cacheie apenas funções puras com argumentos hashable (
lru_cache). Chamecache_clearquando as entradas mudarem externamente. - Defina
maxsizeemlru_cachepara espaços de chave ilimitados. Previne vazamentos de memória. - Use
singledispatchpara extensão aberta por tipo. Não longas cadeiasisinstanceem um módulo. - Use
partialpara vincular configuração, não para ocultar parâmetros obrigatórios. Mantenha assinaturas públicas legíveis.
E - Gerenciadores de Contexto
- Use
withpara arquivos, locks, transações de DB e configuração temporária. Não abra sem um caminho de fechamento. - Use
ExitStackquando o número de contextos for determinado em tempo de execução. Listas de arquivos dinâmicas, pilhas de plugins. - Retorne
Falsede__exit__a menos que esteja deliberadamente suprimindo. Falhas ocultas corrompem o estado. - Prefira
@contextmanagerpara configuração/desmontagem simples com menos de 15 linhas. Baseado em classe para objetos reutilizáveis. - Teste caminhos de rollback injetando exceções dentro do bloco
with.
FAQs
gerador ou list comprehension?
Gerador quando o stream é grande ou de passagem única. Lista quando precisar de len, reutilização ou indexação.
quantos estágios de pipeline?
Divida quando cada estágio tiver uma responsabilidade que mereça um nome - evite aninhamentos anônimos de 10 linhas.
decorator na API pública da biblioteca?
Documente a ordem de empilhamento e a preservação de metadados - consumidores confiam em __name__ nos logs.
lru_cache em métodos?
Cache por função; argumentos de método incluem self - considere uma função fora da classe ou __hash__ em self imutável.
iterador tee?
Apenas quando precisar bifurcar uma passagem única - a memória cresce com a divergência.
práticas de gerador async?
Veja a seção asyncio - use async with para aquisição, async for para consumo.
testando pipelines preguiçosos?
list(pipeline(data)) em testes; afirme a limpeza intermediária com mocks em close.
reduce ainda é ok?
Bom para folds raros; loop explícito geralmente é mais claro para equipes novas em estilo funcional.
decorator de classe vs herança?
Decorator para registro/metadados; herança para implementação de comportamento compartilhado.
maior erro de iterador?
Materializar listas intermediárias gigantes entre estágios de map/filter - permaneça preguiçoso até a fronteira.
Relacionados
- Geradores & yield - pipelines preguiçosos
- Escrevendo Decorators - wraps e fábricas
- Gerenciadores de Contexto - protocolo de limpeza
- Comprehensions & Expressões Geradoras - noções básicas de genexp
Versões do Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.