ContextLib | Python
- ContextLib | Python
🧱 O que é contextmanager
O contextmanager é um decorador da biblioteca padrão contextlib que permite criar contextos gerenciados — ou seja, blocos que funcionam com o with, sem precisar criar uma classe com __enter__ e __exit__.
👉 Ele simplifica o uso de recursos que precisam ser abertos e depois fechados com segurança (como arquivos, conexões, locks, etc.).
⚙️ Exemplo Básico
from contextlib import contextmanager
@contextmanager
def abrir_arquivo(caminho, modo):
print("Abrindo arquivo...")
f = open(caminho, modo)
try:
yield f # entrega o recurso para o bloco 'with'
finally:
print("Fechando arquivo...")
f.close()
# Uso
with abrir_arquivo("exemplo.txt", "w") as arquivo:
arquivo.write("Olá, mundo!")
🧩 Explicação:
@contextmanagertransforma a função em um gerenciador de contexto.- Tudo antes do
yieldé executado ao entrar no contexto. - O valor retornado pelo
yieldé entregue aoas ...nowith. - O bloco depois do
yield(ou nofinally) roda ao sair do contexto, mesmo com erro.
🧰 Tratando Exceções Dentro do Contexto
from contextlib import contextmanager
@contextmanager
def exemplo():
print("Entrando no contexto")
try:
yield
except Exception as e:
print(f"Ocorreu erro: {e}")
finally:
print("Saindo do contexto")
with exemplo():
print("Executando algo...")
raise ValueError("Erro simulado")
Saída:
Entrando no contexto
Executando algo...
Ocorreu erro: Erro simulado
Saindo do contexto
🔒 Uso Real: Locks, Conexões e Temporários
import threading
from contextlib import contextmanager
lock = threading.Lock()
@contextmanager
def sincronizado():
lock.acquire()
try:
yield
finally:
lock.release()
with sincronizado():
print("Executando seção crítica com lock.")
🧠 Dica Extra: contextlib.ExitStack
Se precisar gerenciar múltiplos contextos dinamicamente, use:
from contextlib import ExitStack
with ExitStack() as stack:
f1 = stack.enter_context(open("a.txt", "w"))
f2 = stack.enter_context(open("b.txt", "w"))
f1.write("Arquivo A")
f2.write("Arquivo B")
🧾 Resumo Rápido
| Elemento | Função |
|---|---|
@contextmanager | Cria contexto sem precisar de classe |
yield | Entrega o recurso ao bloco with |
try/finally | Garante limpeza mesmo com erro |
ExitStack | Gerencia vários contextos dinamicamente |