0Pricing
Python Academy · Aula

Protocolo __enter__ e __exit__

Crie gerenciadores de contexto usando o protocolo dunder.

Protocolo __enter__ e __exit__ é uma aula grátis de Python Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Python Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Python Academy inclui 4 aulas no total.

O protocolo de gerenciador de contexto

Qualquer objeto que defina __enter__ e __exit__ é um gerenciador de contexto e pode ser usado com with.

class Managed:
    def __enter__(self):
        print("entering")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exiting")
        return False

with Managed() as m:
    print("inside")

Valor de retorno de __enter__

__enter__ é chamado no início do bloco with. Seu valor de retorno é associado à variável depois de as.

class Resource:
    def __enter__(self):
        self.value = 42
        return self  # bound to 'r'

    def __exit__(self, *args):
        self.value = None
        return False

with Resource() as r:
    print(r.value)  # 42

Argumentos de __exit__

__exit__(exc_type, exc_val, exc_tb) recebe informações sobre a exceção se um erro tiver ocorrido. Se não houver exceção, os três valores serão None.

class Safe:
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is ValueError:
            print(f"Suppressed ValueError: {exc_val}")
            return True   # suppress the exception
        return False      # re-raise anything else

with Safe():
    raise ValueError("oops")  # suppressed

Suprimindo exceções

Retorne True de __exit__ para suprimir a exceção. Retorne False (ou não retorne nada) para permitir que ela seja propagada.

class Ignore:
    def __enter__(self): return self
    def __exit__(self, *args): return True  # swallow all exceptions

with Ignore():
    1 / 0

print("continues here")

Um exemplo de conexão com banco de dados

Um caso de uso clássico: adquirir uma conexão ao entrar, confirmar ou desfazer a transação e fechar ao sair.

class DBConn:
    def __enter__(self):
        self.conn = connect_db()
        return self.conn

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            self.conn.rollback()
        else:
            self.conn.commit()
        self.conn.close()
        return False

Um gerenciador de contexto Timer

Meça o tempo decorrido registrando o início em __enter__ e calculando a diferença em __exit__.

import time

class Timer:
    def __enter__(self):
        self.start = time.perf_counter()
        return self

    def __exit__(self, *args):
        self.elapsed = time.perf_counter() - self.start
        print(f"Elapsed: {self.elapsed:.3f}s")
        return False

with Timer():
    sum(range(1_000_000))

Aninhando gerenciadores de contexto

Vários gerenciadores de contexto podem ser combinados em uma única linha de with.

with open("in.txt") as src, open("out.txt", "w") as dst:
    dst.write(src.read())

Gerenciadores reutilizáveis vs de uso único

Os gerenciadores de contexto cujo __enter__ aloca um recurso novo a cada vez são reutilizáveis. Aqueles que esgotam um estado interno (como um bloqueio mantido apenas uma vez) podem não ser.

class Reusable:
    def __enter__(self):
        return []
    def __exit__(self, *a):
        return False

for _ in range(3):
    with Reusable() as lst:
        lst.append(1)
        print(lst)  # [1] each time

__aenter__ e __aexit__ (assíncronos)

Para gerenciadores de contexto assíncronos, defina corrotinas __aenter__ e __aexit__ e use async with.

class AsyncDB:
    async def __aenter__(self):
        self.conn = await connect()
        return self.conn

    async def __aexit__(self, *args):
        await self.conn.close()

# async with AsyncDB() as conn:
#     ...

Envolvendo objetos de arquivo

Os objetos de arquivo do Python já implementam o protocolo de gerenciador de contexto — nunca chame f.close() manualmente.

with open("data.txt", "r") as f:
    data = f.read()
# file is closed here automatically
print(f.closed)  # True

Implementando um Lock

Bloqueios de threads são gerenciadores de contexto: __enter__ adquire o bloqueio e __exit__ o libera.

import threading

lock = threading.Lock()

def update_shared():
    with lock:
        # critical section
        pass

Verificação rápida

O que __exit__ deve retornar para suprimir uma exceção?

Recapitulação

Implemente __enter__ e __exit__ para criar gerenciadores de contexto. Retorne o recurso de __enter__ e trate a limpeza e a supressão de exceções em __exit__.

Perguntas Frequentes

A aula “Protocolo __enter__ e __exit__” é grátis?

Sim — o texto completo de “Protocolo __enter__ e __exit__” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Python Academy, atualize para CoddyKit PRO. O curso de Python Academy inclui 4 aulas no total.

O que vou aprender em “Protocolo __enter__ e __exit__”?

Crie gerenciadores de contexto usando o protocolo dunder. Você pratica Python Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Python Academy?

Nenhuma experiência prévia é necessária. Python Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Protocolo __enter__ e __exit__”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Python Academy?

Sim. Cada aula de Python Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. A instrução with em profundidade
  2. Protocolo __enter__ e __exit__
  3. contextlib: @contextmanager
  4. Padrões práticos de gerenciadores de contexto
← Voltar para Python Academy