Protokollet __enter__ och __exit__
Skapa kontexthanterare med dunder-protokollet.
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) # 42Argument 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") # suppressedUndertrycka 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 FalseEn 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) # TrueImplementera 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
passSnabbkontroll
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__.
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
- with-satsen på djupet
- Protokollet __enter__ och __exit__
- contextlib: @contextmanager
- Praktiska mönster för kontexthanterare