Como usar gerenciadores de contexto em Python (com instrução)

Aprenda como os gerenciadores de contexto funcionam em Python. Domine a instrução with, gerencie recursos do sistema e escreva gerenciadores de contexto personalizados.

Experimente esta solução no Editor

Visão geral

O gerenciamento adequado de recursos externos, como fechar identificadores de arquivos, desconectar conexões de banco de dados e liberar bloqueios de thread, é essencial para criar software confiável e pronto para produção. A falha na liberação de recursos pode resultar em vazamentos de memória, erros de bloqueio de arquivos e travamentos de aplicativos.

A instrução `with` do Python simplifica a limpeza de recursos criando um gerenciador de contexto. Um gerenciador de contexto garante que as ações de limpeza sejam executadas automaticamente quando o controle sai do bloco, mesmo se o código lançar uma exceção ou sair mais cedo. Isso elimina a necessidade de blocos `try-finally` repetitivos e detalhados.

Embora os gerenciadores de contexto sejam mais comumente associados a operações integradas como `open()`, você pode facilmente projetar seus próprios gerenciadores de contexto personalizados. Você pode construí-los criando uma classe que implemente os métodos mágicos `__enter__` e `__exit__` ou escrevendo uma função geradora decorada com o decorador `contextlib.contextmanager`.

Saída de código e execução

Este script demonstra a criação de gerenciadores de contexto personalizados em Python usando implementações de classe e decoradores contextlib.

context_managers.py
Experimente no Editor
from contextlib import contextmanager

# Method 1: Class-based context manager
class CustomResource:
    def __enter__(self):
        print("[Resource] Opening connection...")
        return self

    def do_work(self):
        print("[Resource] Performing action...")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("[Resource] Closing connection safely.")
        return False

print("--- Class Context Manager ---")
with CustomResource() as resource:
    resource.do_work()

# Method 2: Generator-based context manager (contextlib)
@contextmanager
def simple_timer():
    print("\n[Timer] Started...")
    try:
        yield
    finally:
        print("[Timer] Finished!")

print("\n--- Decorator Context Manager ---")
with simple_timer():
    print("Performing tasks inside context...")
Saída terminal
--- Class Context Manager ---
[Resource] Opening connection...
[Resource] Performing action...
[Resource] Closing connection safely.

--- Decorator Context Manager ---

[Timer] Started...
Performing tasks inside context...
[Timer] Finished!

Implementação passo a passo

  • Use a instrução with ao abrir arquivos, bancos de dados ou bloqueios para garantir a segurança dos recursos.
  • Defina gerenciadores de contexto personalizados usando classes com métodos mágicos __enter__ e __exit__.
  • Use o decorador @contextlib.contextmanager em uma função geradora como uma alternativa mais simples baseada em função.
  • Coloque ações de fechamento de recursos dentro do bloco de limpeza para garantir que sejam executadas mesmo se ocorrerem erros.

Perguntas frequentes

Quais parâmetros o método __exit__ recebe?

O método __exit__ recebe três argumentos representando os detalhes da exceção se alguma for gerada: exc_type (tipo de exceção), exc_val (valor de exceção) e exc_tb (traceback). Se nenhum erro ocorreu, todos os três serão passados ​​como Nenhum.

Um gerenciador de contexto pode suprimir exceções?

Sim. Se o método __exit__ retornar um valor verdadeiro (como True), o Python suprime a exceção e a execução continua após o bloco with. Se retornar False, a exceção será levantada normalmente.

Tópicos Relacionados

Recursos Python recomendados

Expanda seu conhecimento com tutoriais interativos relacionados, folhas de dicas e comparações de código.