Async e Await em Python

0 – Python
4 – Paralela e Concorrente
4.1 – Multithreading (threading)
4.2 – Multiprocessamento (multiprocessing)
4.3 – Assíncrona (asyncio)
4.4 – async ou await
4.4 – Distribuida
LEGENDA
Nivel_1
Nivel_2
Nivel_3

Async e await são palavras-chave para programação assíncrona em Python. Elas foram introduzidas no Python 3.5 para facilitar a concorrência. Primeiramente, async def define uma função assíncrona (corrotina). Dentro dela, await pausa a execução sem bloquear a thread. Por exemplo, await asyncio.sleep(1) espera 1 segundo cooperativamente. Além disso, você só pode usar await dentro de funções async. Assim, o código se torna mais claro e previsível. Consequentemente, a legibilidade melhora drasticamente. Quando utilizar async/await? Em operações de I/O com alta concorrência. Por exemplo, requisições HTTP, acesso a banco de dados ou WebSockets. Por outro lado, async/await não é para tarefas com CPU intensiva. Portanto, identifique primeiro o tipo do seu gargalo. Vamos explorar sintaxe, padrões e boas práticas. Três subtítulos guiarão você pelo coração da programação assíncrona. Finalmente, você dominará async e await em Python.

Sintaxe básica: async def, await e asyncio.run

Uma corrotina é definida com async def nome(). Para chamar uma corrotina, você precisa usar await. O ponto de entrada principal usa asyncio.run(corrotina()). Então, isso cria um event loop e executa a corrotina até completar. Quando usar funções async? Sempre que houver espera por I/O. Por exemplo, leitura de arquivos ou chamadas de rede. Exemplo básico mostrando a sintaxe fundamental:

Use create_task() para agendar corrotinas concorrentes. Use gather() para esperar várias corrotinas simultaneamente. Nunca esqueça de await em chamadas de corrotinas. Assim, você evita erros comuns de iniciantes.

Padrões avançados: timeout, wait e as_completed

Async/await oferece ferramentas para controlar a execução. asyncio.wait_for() adiciona timeout a uma corrotina. asyncio.wait() espera múltiplas tarefas com condições. asyncio.as_completed() processa resultados conforme terminam. Quando usar esses padrões? Em sistemas que exigem limites de tempo. Também em pipelines onde você quer respostas parciais. Além disso, timeouts previnem travamentos eternos. Exemplo prático com timeout e processamento parcial:

Timeouts previnem travamentos em operações lentas. as_completed é ótimo para mostrar progresso gradual. shield protege tarefas importantes de cancelamento. Portanto, use essas ferramentas para sistemas robustos.

Async/await vs. threads vs. callbacks tradicionais

Async/await é muito mais legível que callbacks aninhados. Ele também usa menos memória que threads para muitas conexões. No entanto, threads são melhores para código síncrono legado. Quando escolher async/await? Em projetos novos com muito I/O. Também quando você precisa de milhares de conexões simultâneas. Além disso, async/await facilita o tratamento de erros. A fórmula de legibilidade mostra vantagem clara: \(L = \frac{N_{\text{linhas}}}{N_{\text{aninhamento}}}\) Async/await reduz aninhamento comparado a callbacks. Exemplo comparando callbacks vs. async/await:

Async/await torna o código assíncrono tão legível quanto síncrono. Use return_exceptions=True no gather para lidar com falhas. A regra de ouro: toda operação de I/O deve ser async. Comece com async/await em novas funções de rede. Gradualmente, converta código síncrono legado. Você nunca mais vai querer voltar para callbacks. Portanto, abrace async/await em seus próximos projetos.

Deixe um comentário