Módulo 7 - Geradores e iteradores avançados
send e corrotinas: a ponte para o async
10 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026
O que você vai aprender
- Entender que yield também pode receber um valor, não só produzir.
- Usar o método send para enviar dados a um gerador.
- Reconhecer uma corrotina baseada em gerador.
- Ligar esse conceito à programação assíncrona que vem depois.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: send e corrotinas: a ponte para o async.
Os objetivos desta aula. Entender que yield também pode receber um valor, não só produzir. Usar o método send para enviar dados a um gerador. Reconhecer uma corrotina baseada em gerador. Ligar esse conceito à programação assíncrona que vem depois.
Veja o essencial, parte por parte.
O yield também recebe valores. Além de produzir com yield, um gerador pode receber valores com o método send.
Isso é uma corrotina. Um gerador que recebe valores com send tem um nome: corrotina baseada em gerador.
A ponte para a programação assíncrona. Uma corrotina pausa em um ponto e devolve o controle, mantendo o estado.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
O yield também recebe valores
Até aqui o yield foi uma via de mão única: o gerador produz um valor e quem consome recebe. Mas o yield também pode ser uma expressão que recebe um valor de volta. Quando você escreve recebido = yield, o gerador pausa naquele ponto e, quando alguém o retoma com o método send, o valor enviado se torna o resultado dessa expressão, ficando guardado em recebido. É uma comunicação de mão dupla: dados saem com o yield e entram com o send.
def acumulador():
total = 0
while True:
valor = yield total # produz o total e espera um novo valor
total += valor # o valor enviado com send() chega aqui
acc = acumulador()
next(acc) # avanca ate o primeiro yield (necessario)
print(acc.send(10)) # 10
print(acc.send(5)) # 15
print(acc.send(3)) # 18valor = yield recebe o que send envia; o gerador vira um acumulador vivo.
Acompanhe o fluxo. Primeiro é preciso avançar o gerador até o primeiro yield, seja com next, seja com send(None); esse passo é conhecido como escorvar a corrotina. A partir daí, cada send envia um número que vira o valor da expressão yield, é somado ao total, e o novo total é produzido de volta. O gerador mantém seu estado, o total, entre as chamadas, funcionando como um pequeno objeto que aprende com o que recebe.
Isso é uma corrotina
Um gerador que recebe valores com send tem um nome: corrotina baseada em gerador. A diferença para uma função comum é profunda. Uma função roda do começo ao fim de uma vez. Uma corrotina pausa em cada yield, devolvendo o controle a quem a chamou, e retoma exatamente de onde parou quando é chamada de novo. Essa capacidade de suspender e continuar, mantendo o estado, é o que permite coordenar muitas tarefas que esperam por coisas diferentes sem travar umas às outras.
Função comum
- Roda do início ao fim de uma vez
- Comunicação só na entrada (argumentos) e saída (return)
- Não guarda estado entre chamadas
- Não pode pausar no meio
Corrotina (gerador com send)
- Pausa em cada yield e retoma depois
- Troca dados nos dois sentidos: yield e send
- Mantém o estado local entre as retomadas
- Suspende e continua de onde parou
Vale ser honesto sobre o escopo desta aula: corrotinas com send à mão são um recurso conceitual mais do que uma ferramenta que você usará todo dia. Elas existem, funcionam, e aparecem em código mais antigo e em situações específicas. O valor de conhecê-las agora é entender o mecanismo de pausar e retomar trocando dados, porque é exatamente esse mecanismo que a programação assíncrona moderna leva adiante, com uma sintaxe muito mais clara.
A ponte para a programação assíncrona
Aqui as peças se juntam. A programação assíncrona resolve um problema concreto: um programa que passa a maior parte do tempo esperando, por respostas de rede, por disco, por outros serviços, poderia usar essa espera para adiantar outras tarefas. Para isso, cada tarefa precisa conseguir pausar quando começa a esperar e devolver o controle, deixando outra tarefa avançar. É precisamente a capacidade de suspender e retomar que você acabou de ver nas corrotinas com yield e send.
No módulo de programação assíncrona, você não vai mais escrever send à mão nem escorvar corrotinas: a sintaxe async def e await cuida disso com muito mais elegância, e um coordenador chamado laço de eventos gerencia quem roda quando. Mas, por baixo, o princípio é o que você viu aqui. Ter enxergado o gerador que pausa, guarda estado e troca dados nos dois sentidos faz o async deixar de parecer mágica e passar a ser a evolução natural de algo que você já entende.
Teste rápido
O que o método send faz em um gerador usado como corrotina?
Perguntas frequentes
- Por que é preciso escorvar a corrotina antes do primeiro send?
- Porque o gerador começa pausado antes da primeira linha; ele precisa avançar até o primeiro yield para ter onde receber um valor. Esse primeiro passo se faz com next(gerador) ou gerador.send(None). Tentar enviar um valor com send antes disso gera um erro, já que não há nenhuma expressão yield esperando por um valor ainda.
- Qual a diferença entre yield que produz e valor = yield?
- O primeiro só produz um valor para quem consome; o segundo também recebe. Em valor = yield algo, o gerador cede algo e pausa; quando retomado com send(x), a expressão yield vira x, guardado em valor. Ou seja, o mesmo yield pode ser via de saída e de entrada ao mesmo tempo, o que caracteriza uma corrotina.
- Preciso usar corrotinas com send no dia a dia?
- Quase nunca de forma manual. A sintaxe moderna async e await cobre os casos práticos de concorrência com muito mais clareza. As corrotinas baseadas em gerador com send são úteis para entender o mecanismo por baixo e aparecem em código mais antigo. Considere esta aula uma base conceitual, não uma técnica de uso frequente.
- Corrotina é a mesma coisa que thread?
- Não. Uma thread é gerenciada pelo sistema operacional e pode rodar em paralelo de verdade em certos casos. Uma corrotina é cooperativa: ela roda sozinha até decidir pausar e devolver o controle, sem paralelismo real por si só. A programação assíncrona usa corrotinas coordenadas por um laço de eventos, um modelo diferente do de threads, que o curso trata em módulos próprios.
- O yield from tem relação com send e corrotinas?
- Tem, e é direta. O yield from não só repassa valores produzidos: ele também encaminha os valores enviados com send ao gerador interno e propaga o retorno. Por isso o yield from foi peça central na construção do async antes da sintaxe moderna. Foi uma das pontes que levaram das corrotinas baseadas em gerador ao async e await de hoje.
Fontes
Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.