Menu
Coddy logo textTech

Gerenciadores de Contexto

Parte da seção Object Oriented Programming do Journey de Python da Coddy — lição 41 de 64.

Gerenciadores de contexto permitem que você aloque e libere recursos precisamente quando necessário. Eles garantem a limpeza adequada mesmo se ocorrerem erros.

Aqui está o exemplo mais comum usando a instrução with:

with open('example.txt', 'w') as file:
    file.write('Hello, world!')
# O arquivo é fechado automaticamente aqui

O arquivo é fechado automaticamente após o bloco, mesmo que ocorra uma exceção.

Crie seu próprio gerenciador de contexto implementando os métodos __enter__ e __exit__:

class MyContext:
    def __enter__(self):
        print("Entering the context")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting the context")
        return False  # Não suprima exceções

Use seu gerenciador de contexto personalizado:

with MyContext() as ctx:
    print("Inside the context")

Saída:

Entering the context
Inside the context
Exiting the context

Crie um gerenciador de contexto mais prático para conexões de banco de dados:

class DatabaseConnection:
    def __init__(self, db_name):
        self.db_name = db_name
        self.connection = None
    
    def __enter__(self):
        print(f"Connecting to {self.db_name}")
        self.connection = f"Connection to {self.db_name}"
        return self.connection
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"Closing connection to {self.db_name}")
        self.connection = None

with DatabaseConnection("users_db") as conn:
    print(f"Using {conn}")
    print("Performing database operations...")

Lide com exceções em gerenciadores de contexto:

class SafeContext:
    def __enter__(self):
        print("Setting up resources")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Cleaning up resources")
        if exc_type:
            print(f"An exception occurred: {exc_val}")
        return False  # Não suprima a exceção

with SafeContext():
    print("Working with resources")
    # raise ValueError("Something went wrong")  # Descomente para testar

Saída:

Connecting to users_db
Using Connection to users_db
Performing database operations...
Closing connection to users_db
Setting up resources
Working with resources
Cleaning up resources

O método __exit__ recebe três parâmetros:

  • exc_type: Tipo da exceção (ou None)
  • exc_val: Valor da exceção (ou None)
  • exc_tb: Traceback da exceção (ou None)

Ponto Chave: Gerenciadores de contexto usam os métodos __enter__ e __exit__ para gerenciar recursos. A instrução with chama automaticamente esses métodos, garantindo a configuração e a limpeza adequadas. Isso é especialmente útil para arquivos, conexões de banco de dados e outros recursos que precisam de limpeza garantida.

challenge icon

Desafio

Fácil

Neste desafio, você implementará uma classe de gerenciador de contexto que mede o tempo decorrido entre a entrada e a saída de um bloco de contexto.

  • timer.py - Contém a implementação da classe Timer (este é o arquivo que você editará)
  • driver.py - Contém casos de teste abrangentes (não modifique)

Implemente o gerenciador de contexto Timer em timer.py seguindo os comentários TODO. A classe deve:

  1. Registrar o tempo de início ao entrar em um contexto
  2. Registrar o tempo de término ao sair
  3. Calcular e exibir o tempo decorrido

Folha de consulta

Gerenciadores de contexto alocam e liberam recursos precisamente quando necessário, garantindo a limpeza adequada mesmo se ocorrerem erros.

Use a instrução with para o gerenciamento automático de recursos:

with open('example.txt', 'w') as file:
    file.write('Hello, world!')
# O arquivo é fechado automaticamente aqui

Crie gerenciadores de contexto personalizados implementando os métodos __enter__ e __exit__:

class MyContext:
    def __enter__(self):
        print("Entering the context")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting the context")
        return False  # Não suprime exceções

with MyContext() as ctx:
    print("Inside the context")

O método __exit__ recebe três parâmetros:

  • exc_type: Tipo da exceção (ou None)
  • exc_val: Valor da exceção (ou None)
  • exc_tb: Traceback da exceção (ou None)

Trate exceções em gerenciadores de contexto:

class SafeContext:
    def __enter__(self):
        print("Setting up resources")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Cleaning up resources")
        if exc_type:
            print(f"An exception occurred: {exc_val}")
        return False  # Não suprime a exceção

Experimente você mesmo

from timer import Timer
import time

# Manipulador de casos de teste
test_case = input()

if test_case == "basic_test":
    # Teste de funcionalidade básica
    with Timer():
        # Simula algum trabalho
        time.sleep(2)  # Isso faz o programa esperar por 2 segundos

elif test_case == "nested_contexts":
    # Testa gerenciadores de contexto aninhados
    with Timer():
        time.sleep(1)
        with Timer():
            time.sleep(1)

elif test_case == "exception_handling":
    # Testa o tratamento de exceções dentro do contexto
    try:
        with Timer():
            time.sleep(1)
            raise ValueError("Test exception")
    except ValueError as e:
        print(f"Caught exception: {e}")

elif test_case == "zero_sleep":
    # Teste com sleep mínimo
    with Timer():
        time.sleep(0.001)

elif test_case == "multiple_timers":
    # Testa múltiplos timers em sequência
    with Timer():
        time.sleep(1)
    
    with Timer():
        time.sleep(0.5)
    
    with Timer():
        time.sleep(2)

elif test_case == "as_decorator":
    # Testa o timer em um contexto de função
    def timed_function():
        with Timer():
            time.sleep(2)
    
    timed_function()

else:
    # Teste padrão - funcionalidade básica
    with Timer():
        # Simula algum trabalho
        time.sleep(2)  # Isso faz o programa esperar por 2 segundos
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming