0Pricing
Python Academy · Lezione

contextlib: @contextmanager

Crei context manager in modo conciso con il decorator di contextlib.

contextlib: @contextmanager è una lezione Python Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Python Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Python Academy include 4 lezioni in totale.

Perché contextlib?

contextlib.contextmanager consente di scrivere un gestore di contesto come funzione generatrice anziché come classe, riducendo il codice ripetitivo.

from contextlib import contextmanager

@contextmanager
def managed():
    print("setup")
    yield
    print("teardown")

with managed():
    print("inside")

Restituire un valore

Qualunque valore venga restituito da yield viene assegnato alla variabile as nell'istruzione with.

from contextlib import contextmanager

@contextmanager
def temp_list():
    lst = []
    yield lst
    print(f"Final list: {lst}")

with temp_list() as lst:
    lst.append(1)
    lst.append(2)

Gestione delle eccezioni in @contextmanager

Racchiuda yield in un blocco try/finally per garantire la pulizia anche se si verifica un'eccezione.

from contextlib import contextmanager

@contextmanager
def safe_open(path):
    f = open(path)
    try:
        yield f
    finally:
        f.close()

with safe_open("data.txt") as f:
    print(f.read())

Soppressione delle eccezioni

Intercetti l'eccezione all'interno del generatore per sopprimerla: è equivalente a restituire True da __exit__.

from contextlib import contextmanager

@contextmanager
def ignore_value_errors():
    try:
        yield
    except ValueError:
        pass

with ignore_value_errors():
    raise ValueError("ignored")

contextlib.suppress

contextlib.suppress(*exceptions) è un gestore di contesto già pronto che sopprime i tipi di eccezione specificati.

from contextlib import suppress

with suppress(FileNotFoundError):
    open("missing.txt")

print("continues")

contextlib.closing

closing(obj) crea un gestore di contesto che chiama obj.close() all'uscita. È utile per gli oggetti che dispongono di close() ma non di __exit__.

from contextlib import closing
from urllib.request import urlopen

with closing(urlopen("https://example.com")) as page:
    content = page.read()

contextlib.nullcontext

nullcontext è un gestore di contesto che non esegue alcuna operazione. È utile quando l'uso di un gestore di contesto è opzionale.

from contextlib import nullcontext

def process(data, lock=None):
    cm = lock if lock is not None else nullcontext()
    with cm:
        return [x*2 for x in data]

contextlib.ExitStack

ExitStack consente di gestire dinamicamente un numero variabile di gestori di contesto.

from contextlib import ExitStack

files = ["a.txt", "b.txt", "c.txt"]
with ExitStack() as stack:
    handles = [stack.enter_context(open(f)) for f in files]
    data = [h.read() for h in handles]

Riutilizzare un @contextmanager

Un gestore di contesto basato su un generatore può essere utilizzato una sola volta per chiamata. Per riutilizzarlo, chiami nuovamente la funzione decorata.

from contextlib import contextmanager

@contextmanager
def counter():
    count = 0
    yield lambda: count.__add__  # each call is independent
    print("done")

with counter():
    pass
with counter():
    pass

asynccontextmanager

Per il codice asincrono, utilizzi contextlib.asynccontextmanager per scrivere gestori async with come generatori.

from contextlib import asynccontextmanager

@asynccontextmanager
async def async_session():
    session = await create_session()
    try:
        yield session
    finally:
        await session.close()

contextlib.redirect_stdout

Reindirizzi temporaneamente l'output standard verso un oggetto simile a un file.

import io
from contextlib import redirect_stdout

buf = io.StringIO()
with redirect_stdout(buf):
    print("captured")

print(buf.getvalue())  # captured

Controllo rapido

In un generatore @contextmanager, dove deve essere inserito il codice di pulizia per garantire che venga eseguito anche in caso di eccezione?

Riepilogo

@contextmanager trasforma un generatore in un gestore di contesto. Utilizzi try/finally intorno a yield per una pulizia sicura. Il modulo contextlib fornisce anche suppress, nullcontext, ExitStack e altro.

Domande Frequenti

La lezione «contextlib: @contextmanager» è gratuita?

Sì — il testo completo di «contextlib: @contextmanager» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Python Academy, passa a CoddyKit PRO. Il corso Python Academy include 4 lezioni in totale.

Cosa imparerò in «contextlib: @contextmanager»?

Crei context manager in modo conciso con il decorator di contextlib. Eserciti Python Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Python Academy?

Non è richiesta alcuna esperienza precedente. Python Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «contextlib: @contextmanager»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Python Academy?

Sì. Ogni lezione Python Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. L'istruzione with in dettaglio
  2. Protocollo __enter__ e __exit__
  3. contextlib: @contextmanager
  4. Schemi pratici per i context manager
← Torna a Python Academy