✅ Atualizado para Python 3.13 (Dezembro 2025) Conteúdo enriquecido com comparação async vs sync vs threading e quando usar cada abordagem.
Salve salve Pythonista!
Programação Assíncrona permite que seu código execute múltiplas tarefas de I/O concorrentemente sem criar threads. É ideal para operações I/O-bound como requisições HTTP, banco de dados e arquivos.
Neste guia completo, você vai aprender:
- ✅ O que é programação assíncrona
- ✅ async/await e coroutines
- ✅ asyncio - biblioteca padrão
- ✅ Async vs Sync vs Threading - quando usar cada um
- ✅ Casos de uso práticos (APIs, I/O)
Prepare-se para muitos exemplos práticos e um mini-projeto utilizando programação assíncrona!
Vá Direto ao Assunto…
- Introdução à Programação Assíncrona
- Como o Processador e o Sistema Operacional Tratam a Programação Assíncrona
- Programando Assincronamente em Python
- Programação Assíncrona com aiohttp
- Exemplos de Programação Assíncrona em Python
- Mini Projeto com Programação Assíncrona
- Async vs Sync vs Threading: Quando Usar?
Introdução à Programação Assíncrona
Vamos começar pelo princípio: o que é programação assíncrona?
Em duas palavra, programação assíncrona é sobre não esperar.
Normalmente, quando o nosso código necessita de algum recurso, seja um arquivo no disco, um dado vindo da rede, ou simplesmente um cálculo longo, ele simplesmente para e espera esse recurso ficar disponível.
Nesse meio tempo, o processador fica lá, sem fazer nada.
Agora imagine se em vez de esperar, ele pudesse executar outra parte do código que não dependesse desse recurso?
É exatamente isso que a programação assíncrona faz.
Em vez de bloquear a execução esperando algum recurso, o código é capaz de “pular” essa parte e continuar a execução em outro lugar.
Quando o recurso finalmente fica disponível, o código pode retomar de onde parou.
Agora vamos ao “Hello World” da programação assíncrona com Python:
1
2
3
4
5
6
7
8
9
import asyncio
async def main():
print('Olá ...')
await asyncio.sleep(5)
print('... Mundo')
# Python 3.7+
asyncio.run(main())
E como aqui na Python Academy nós gostamos de te entregar tudo mastigado, vamos às explicações:
-
async def main(): Esta é a definição de uma função assíncrona. A palavra-chaveasyncindica que a função é assíncrona e pode usarawaitpara aguardar outras operações assíncronas. -
await asyncio.sleep(5): Esta linha faz a funçãomainaguardar assincronamente por 5 segundos. Durante este tempo, outras partes do programa podem continuar executando.asyncio.sleep(5)é uma função assíncrona que simula uma operação de bloqueio (como uma operação de I/O), mas sem realmente bloquear. -
asyncio.run(main()): Esta é a maneira de iniciar e gerenciar a execução da função assíncronamain().asyncio.runé uma função que executa a coroutinemain()e não retorna até que amain()esteja completa.
Como o Processador e o Sistema Operacional Tratam a Programação Assíncrona
A verdade é que, internamente, o processador e o sistema operacional não estão fazendo nada muito diferente quando se trata de programação assíncrona.
O que muda é a forma como o programa é estruturado.
O programa consegue organizar-se de forma que o processador sempre tem algum código para executar, nunca ficando parado.
A biblioteca asyncio que vimos no exemplo anterior é um exemplo de um tipo de sistema chamado event loop.
A função asyncio.run() que usamos para executar nosso código assíncrono na verdade está iniciando um event loop, e o await asyncio.sleep(5) está suspendendo a execução da função e retornando o controle à este event loop.
Programando Assincronamente em Python
Trabalhar com código assíncrono em Python é bastante direto, graças à introdução das palavras-chave async e await a partir do Python 3.5.
Basicamente, uma função é declarada como assíncrona usando a palavra-chave async def no lugar de def:
1
2
async def minha_funcao():
print("Olá, Mundo Assíncrono!")
Agora, essa função é uma coroutine, e pode ser pausada e retomada.
A pausa é feita através da palavra-chave await, seguida de uma expressão que retorna uma coroutine:
1
2
3
4
async def minha_funcao():
print("Iniciando...")
await asyncio.sleep(1)
print("...terminou!")
Nesse exemplo, a função asyncio.sleep(1) é uma coroutine que simula um delay de 1 segundo.
Mas em vez de bloquear a execução, ela apenas indica ao event loop que a execução atual deve ser suspensa, e que deve ser retomada depois do tempo especificado.
Criei o Ebookr.ai, uma plataforma que usa IA para gerar ebooks profissionais sobre qualquer tema — com capa gerada por IA, infográficos automáticos e exportação em PDF. Confere!
Programação Assíncrona com aiohttp
Python já vem com várias bibliotecas prontas para auxiliar na programação assíncrona, sendo a mais conhecida delas a asyncio, que já mencionamos antes.
Além dela, podemos fazer a instalação da aiohttp para fazer requisições HTTP assíncronas com pip install aiohttp.
Vamos ver um exemplo de como utilizá-la para fazer requisições assíncronas ao site Oficial do Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
html = await fetch(session, 'http://python.org')
print(html)
asyncio.run(main())
Nesse exemplo, a função fetch() está fazendo uma requisição HTTP usando a biblioteca aiohttp.
Ela é uma função assíncrona, e pode ser pausada e retomada.
Note que estamos usando a palavra await tanto para esperar a resposta HTTP como para ler o texto da resposta.
Ao final da execução, você verá o código HTML da página na saída do programa!
Exemplos de Programação Assíncrona em Python
Vamos mostrar agora alguns exemplos de utilização da programação assíncrona em Python.
Exemplo 1: Função Assíncrona simples
1
2
3
4
5
6
7
8
9
import asyncio
async def contar_ate_dez():
for i in range(10):
print(i)
await asyncio.sleep(1)
print("Contei até dez!")
asyncio.run(contar_ate_dez())
A função contar_ate_dez() é uma função assíncrona que imprime os números de 0 a 9, com um intervalo de 1 segundo entre eles.
Ela utiliza o comando await asyncio.sleep(1) para esperar assincronamente por 1 segundo.
Colocando-o em execução, você verá a seguinte saída:
1
2
3
4
5
6
7
8
9
10
11
0
1
2
3
4
5
6
7
8
9
Contei até dez!
Está curtindo esse conteúdo? ![]()
Que tal receber 30 dias de conteúdo direto na sua Caixa de Entrada?
Exemplo 2: Executando múltiplas coroutines
Vamos ver nesse exemplo como executar múltiplas funções assíncronas:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import asyncio
async def contar_ate_dez(nome):
for i in range(10):
print(f'{nome}: {i}')
# Simula uma operação demorada...
await asyncio.sleep(1)
async def main():
await asyncio.gather(
contar_ate_dez('Tarefa 1'),
contar_ate_dez('Tarefa 2')
)
asyncio.run(main())
Esse exemplo mostra como executar várias coroutines em paralelo.
A função asyncio.gather() é usada para combinar várias coroutines em uma única tarefa.
Elas serão executadas assincronamente, e a função await asyncio.gather() só vai completar quando todas elas tiverem completado.
Mini Projeto com Programação Assíncrona
Para terminar, vamos fazer um mini-projeto utilizando programação assíncrona.
Vamos fazer um Crawler simples que vai baixar várias páginas web em paralelo.
Ele utilizará o aiohttp, portanto não esqueça de fazer sua instalação com pip install aiohttp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import asyncio
import aiohttp
lista_urls = [
'http://python.org',
'http://google.com',
'http://facebook.com',
# Adicione quantas URLs quiser aqui...
]
async def fetch_page(session, url):
async with session.get(url) as response:
return await response.text()
async def fetch_all_pages():
async with aiohttp.ClientSession() as session:
tasks = []
for url in lista_urls:
tasks.append(fetch_page(session, url))
pages = await asyncio.gather(*tasks)
return pages
async def main():
pages = await fetch_all_pages()
for i, page in enumerate(pages):
print(f'PÁGINA {i}:\n {page[:150]}...\n\n{"*" * 30}')
asyncio.run(main())
Nesse código, fetch_page() é uma coroutine que baixa uma página web usando a biblioteca aiohttp.
A função fetch_all_pages() usa a função asyncio.gather() para baixar todas as páginas em paralelo, e retorna uma lista com o conteúdo de todas elas.
Ao final da sua execução, será mostrado os 150 primeiros caracteres de cada página:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PÁGINA 0:
<!doctype html>
<!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 lt-ie8 lt-...
******************************
PÁGINA 1:
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="pt-BR"><head><meta content="text/html; charset=UTF-8" http-equiv="Content...
******************************
PÁGINA 2:
<!DOCTYPE html>
<html lang="pt" id="facebook" class="no_js">
<head><meta charset="utf-8" /><meta name="referrer" content="default" id="meta_referrer" ...
******************************
Em posse desses dados, você pode fazer qualquer tipo de processamento!
Você pode acessar outras páginas, como páginas de notícias, e-commerces para verificação de preços entre outras várias possibilidades!
Async vs Sync vs Threading: Quando Usar?
Programação Síncrona (Normal)
Use quando:
- ✅ Tarefas CPU-bound (cálculos intensivos)
- ✅ Código simples e direto
- ✅ Sem I/O ou I/O mínimo
- ✅ Projeto pequeno
1
2
3
4
# Síncrono: uma tarefa por vez
def processar_dados(data):
resultado = calcular(data) # Bloqueia aqui
return resultado
Programação Assíncrona (async/await)
Use quando:
- ✅ Tarefas I/O-bound (rede, disco, DB)
- ✅ Múltiplas requisições HTTP simultaneamente
- ✅ Single-threaded (sem problemas de concorrência)
- ✅ Quer escalabilidade (milhares de conexões)
1
2
3
4
5
6
7
8
# Assíncrono: não bloqueia durante I/O
import asyncio
async def fetch_data(url):
# Enquanto espera resposta, executa outras tarefas
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
Threading/Multiprocessing
Use Threading quando:
- ✅ Tarefas I/O-bound sem suporte assíncrono
- ✅ Bibliotecas síncronas (sem async)
- ✅ Paralelismo simples (poucas threads)
Use Multiprocessing quando:
- ✅ Tarefas CPU-bound (cálculos intensivos)
- ✅ Precisa verdadeiro paralelismo (contornar GIL)
- ✅ Processamento de dados massivos
Comparação Rápida
| Abordagem | I/O-bound | CPU-bound | Escalabilidade | Complexidade |
|---|---|---|---|---|
| Síncrono | ❌ Lento | ✅ OK | ❌ Baixa | ✅ Simples |
| Async | ✅ Rápido | ❌ Ruim | ✅ Alta | ⚠️ Média |
| Threading | ✅ Bom | ❌ Ruim (GIL) | ⚠️ Média | ⚠️ Média |
| Multiprocessing | ❌ Overhead | ✅ Excelente | ⚠️ Média | ❌ Complexo |
Casos de Uso Práticos
Async: Web scraping, APIs REST, WebSockets, chat servers Threading: Download de arquivos, GUI responsivas Multiprocessing: Processamento de imagens, ML training, análise de dados Síncrono: Scripts simples, cálculos, ETL básico
💡 Regra de Ouro: Se é I/O-bound (rede, disco), use async. Se é CPU-bound (cálculos), use multiprocessing.
Conclusão
Neste guia completo sobre Programação Assíncrona, você aprendeu:
✅ Conceito - Concorrência sem threads ✅ async/await - Palavras-chave para coroutines ✅ asyncio - Biblioteca padrão para async ✅ Async vs Sync vs Threading - Quando usar cada um ✅ Casos de uso - APIs, I/O, web scraping
Principais lições:
- Async é ideal para tarefas I/O-bound (rede, disco)
- NÃO use async para CPU-bound (use multiprocessing)
- Async oferece alta escalabilidade (milhares de conexões)
-
asyncioé a biblioteca padrão (sem instalação extra) - Evite mixing sync e async no mesmo código
Próximos passos:
- Pratique com
aiohttppara requisições HTTP - Explore frameworks async (FastAPI, aiohttp.web)
- Estude
asyncio.gather()para executar múltiplas tarefas - Aprenda sobre async context managers e iterators
Com a programação assíncrona, seu código nunca mais precisará ficar parado esperando I/O!
Espero que esse tutorial tenha sido útil, e até a próxima, Pythonista!
"Porque o Senhor dá a sabedoria, e da sua boca vem a inteligência e o entendimento" Pv 2:6