Generators, Iterators e Async
Aula 8 de 10
Iterators
class Contador:
def __init__(self, max):
self.max = max
self.atual = 0
def __iter__(self):
return self
def __next__(self):
if self.atual >= self.max:
raise StopIteration
self.atual += 1
return self.atual
for n in Contador(5):
print(n) # 1, 2, 3, 4, 5
Generators
# Generator function
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
for _ in range(10):
print(next(fib)) # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
# Generator expression
quadrados = (x**2 for x in range(10))
print(list(quadrados))
# Pipeline com generators
def ler_linhas(arquivo):
for linha in open(arquivo):
yield linha.strip()
def filtrar(linhas, padrao):
for linha in linhas:
if padrao in linha:
yield linha
def contar(palavras):
from collections import Counter
return Counter(palavras)
# pipeline = contar(filtrar(ler_linhas("log.txt"), "ERROR"))
Async/Await
import asyncio
async def tarefa(nome, tempo):
print(f"{nome}: iniciando")
await asyncio.sleep(tempo)
print(f"{nome}: concluído após {tempo}s")
return f"Resultado de {nome}"
async def main():
# Sequencial
await tarefa("A", 2)
await tarefa("B", 1)
# Paralelo
resultados = await asyncio.gather(
tarefa("C", 3),
tarefa("D", 1),
tarefa("E", 2),
)
print(resultados)
# Timeout
try:
await asyncio.wait_for(tarefa("F", 10), timeout=2)
except asyncio.TimeoutError:
print("Timeout!")
asyncio.run(main())
HTTP Async com aiohttp
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as resp:
return await resp.text()
async def main():
async with aiohttp.ClientSession() as session:
tasks = [
fetch(session, f"https://api.github.com/users/{user}")
for user in ["python", "microsoft", "google"]
]
resultados = await asyncio.gather(*tasks)
for r in resultados:
print(len(r))
asyncio.run(main())
Generators criam sequências sem alocar memória para todos os elementos. Async é ideal para I/O-bound (HTTP, bancos, arquivos). Para CPU-bound, use multiprocessing.