Generators em Python são funções especiais que usam yield para gerar valores sob demanda, economizando memória em vez
de criar listas completas na RAM. Pense neles como “listas preguiçosas” que produzem um item por vez, ideais para
processar arquivos grandes ou sequências infinitas sem travar o sistema.
Yield vs Return: A Diferença Fundamental
return encerra a função imediatamente após retornar um único valor, enquanto yield pausa a execução, retorna um
valor e preserva o estado interno para continuar de onde parou na próxima chamada. Isso permite que uma única função
gere múltiplos valores sequencialmente, como um loop “congelado” e retomado.
| |
return é para resultados finais únicos; yield constrói iteradores reutilizáveis.
Como Funcionam os Generators Básicos
Uma função generator parece normal, mas substitui return por yield, que pausa a execução e retorna um valor,
preservando o estado para continuar depois. Isso cria um objeto iterável consumido com for ou next(), perfeito para
loops sem alocar memória extra.
| |
Vantagens em Memória e Performance
Generators brilham com dados grandes: uma lista de 1 milhão de números usa ~80MB, mas o generator equivalente consome
apenas 128 bytes, gerando itens sob demanda. São nativos para for, list(), sum() e economizam tempo em cenários
reais como leitura de logs ou CSV gigantes.
Expressões geradoras simplificam ainda mais: (x**2 for x in range(1000000)) cria um generator conciso sem parênteses
extras, consumido iterativamente.
Tratamento de Exceções Simples
Exceções funcionam naturalmente dentro do generator. Use try/except para capturar erros durante a geração, como
valores inválidos em um parser de JSON, mantendo o fluxo seguro.
| |
Isso previne crashes em dados reais “sujos”, comuns em automações e ETLs.
Fechamento Correto de Resources
Generators com arquivos ou conexões precisam de fechamento para evitar vazamentos. Use try/finally internamente ou
generator.close() externamente, garantindo liberação automática.
| |
Context managers (with) integram perfeitamente para automação, eliminando necessidade de close() manual.
| |
Aplicações Práticas Iniciais
- Arquivos gigantes: Leia linha por linha sem carregar tudo.
- Sequências infinitas: Fibonacci ou contadores sem fim.
- Pipelines simples: Filtre e transforme dados em cadeia.
- Testes unitários: Mock de iteradores sem dados reais.
Esses padrões otimizam ERPs, scripts de automação e APIs desde o primeiro projeto.
Conclusão
Generators transformam código Python em soluções eficientes e elegantes. Comece substituindo listas por generators em seus loops e veja a diferença em performance imediatamente.
Teste os exemplos acima no seu próximo projeto Python, meça o uso de memória com sys.getsizeof() e compartilhe seus
resultados em @riverfount@bolha.us para discutirmos otimizações reais juntos!