Python Academy · Lektion

Protokollet __enter__ och __exit__

Skapa kontexthanterare med dunder-protokollet.

Lektion 2 av 413 steg

Protokollet __enter__ och __exit__ är en gratis lektion i Python Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Python Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Python Academy innehåller totalt 4 lektioner.

Protokollet för kontexthanterare

Alla objekt som definierar __enter__ och __exit__ är kontexthanterare och kan användas med 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")

Returvärdet från __enter__

__enter__ anropas i början av with-blocket. Dess returvärde binds till variabeln efter 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

Argument till __exit__

__exit__(exc_type, exc_val, exc_tb) tar emot information om undantaget om ett fel inträffade. Om inget undantag inträffade är alla tre 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

Undertrycka undantag

Returnera True från __exit__ för att undertrycka undantaget. Returnera False (eller ingenting) för att låta det spridas vidare.

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

with Ignore():
    1 / 0

print("continues here")

Exempel med en databasanslutning

Ett klassiskt användningsfall: anslut till databasen vid start och gör commit/rollback samt stäng anslutningen vid avslut.

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

En kontexthanterare för tidtagning

Mät förfluten tid genom att registrera starten i __enter__ och beräkna skillnaden i __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))

Kapsla kontexthanterare

Flera kontexthanterare kan kombineras på en enda with-rad.

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

Återanvändbara kontra engångshanterare

Kontexthanterare vars __enter__ allokerar en ny resurs varje gång kan återanvändas. De som förbrukar ett internt tillstånd (till exempel ett lås som bara hålls en gång) kanske inte kan återanvändas.

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__ och __aexit__ (asynkront)

För asynkrona kontexthanterare definierar Ni koroutinerna __aenter__ och __aexit__ och använder 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:
#     ...

Omsluta filobjekt

Pythons filobjekt implementerar redan protokollet för kontexthanterare – anropa aldrig f.close() manuellt.

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

Implementera ett lås

Trådlås är kontexthanterare: __enter__ förvärvar låset och __exit__ frigör det.

import threading

lock = threading.Lock()

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

Snabbkontroll

Vad ska __exit__ returnera för att undertrycka ett undantag?

Sammanfattning

Implementera __enter__ och __exit__ för att skapa kontexthanterare. Returnera resursen från __enter__ och hantera städning samt undertryckande av undantag i __exit__.

Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
76
Lektioner
320

Vanliga frågor

Är lektionen ”Protokollet __enter__ och __exit__” gratis?

Ja – hela texten till ”Protokollet __enter__ och __exit__” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Python Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Python Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Protokollet __enter__ och __exit__”?

Skapa kontexthanterare med dunder-protokollet. Ni övar på Python Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Python Academy?

Du behöver inga förkunskaper. Utbildningen i Python Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”Protokollet __enter__ och __exit__”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Python Academy-lektionen?

Ja. Varje Python Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. with-satsen på djupet
  2. Protokollet __enter__ och __exit__
  3. contextlib: @contextmanager
  4. Praktiska mönster för kontexthanterare
← Tillbaka till Python Academy