__enter__- og __exit__-protokollen
Opprett kontekstbehandlere ved hjelp av dunder-protokollen.
__enter__- og __exit__-protokollen er en gratis leksjon i Python Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Python Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Python Academy inneholder totalt 4 leksjoner.
Kontekstbehandlerprotokollen
Alle objekter som definerer __enter__ og __exit__, er kontekstbehandlere og kan brukes 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")Returverdien til __enter__
__enter__ kalles i starten av with-blokken. Returverdien bindes til variabelen etter 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) # 42Argumentene til __exit__
__exit__(exc_type, exc_val, exc_tb) mottar informasjon om unntaket hvis det oppstod en feil. Hvis det ikke oppstod noe unntak, er alle 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") # suppressedUndertrykke unntak
Returner True fra __exit__ for å undertrykke unntaket. Returner False (eller ingenting) for å la det videreføres.
class Ignore:
def __enter__(self): return self
def __exit__(self, *args): return True # swallow all exceptions
with Ignore():
1 / 0
print("continues here")Et eksempel med en databaseforbindelse
Et klassisk bruksområde: Hent en forbindelse ved start, utfør commit eller rollback og lukk den ved avslutning.
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 tidsmåler som kontekstbehandler
Mål medgått tid ved å registrere starttidspunktet i __enter__ og beregne differansen 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))Nesting av kontekstbehandlere
Flere kontekstbehandlere kan kombineres på én with-linje.
with open("in.txt") as src, open("out.txt", "w") as dst:
dst.write(src.read())Gjenbrukbare kontra engangsbehandlere
Kontekstbehandlere der __enter__ tildeler en ny ressurs hver gang, kan gjenbrukes. Behandlere som tømmer en intern tilstand (for eksempel en lås som bare holdes én gang), kan ikke nødvendigvis gjenbrukes.
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__ og __aexit__ (asynkront)
For asynkrone kontekstbehandlere definerer De korutinene __aenter__ og __aexit__ og bruker 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:
# ...Pakke inn filobjekter
Python-filobjekter implementerer allerede kontekstbehandlerprotokollen – kall aldri f.close() manuelt.
with open("data.txt", "r") as f:
data = f.read()
# file is closed here automatically
print(f.closed) # TrueImplementere en lås
Trådlåser er kontekstbehandlere: __enter__ låser, og __exit__ låser opp.
import threading
lock = threading.Lock()
def update_shared():
with lock:
# critical section
passKunnskapssjekk
Hva må __exit__ returnere for å undertrykke et unntak?
Oppsummering
Implementer __enter__ og __exit__ for å opprette kontekstbehandlere. Returner ressursen fra __enter__, og håndter opprydding og undertrykking av unntak i __exit__.
Lær deg Python med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 76
- Leksjoner
- 320
Ofte stilte spørsmål
Er leksjonen «__enter__- og __exit__-protokollen» gratis?
Ja – hele teksten i «__enter__- og __exit__-protokollen» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Python Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Python Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «__enter__- og __exit__-protokollen»?
Opprett kontekstbehandlere ved hjelp av dunder-protokollen. Du øver på Python Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Python Academy?
Ingen tidligere erfaring er nødvendig. Python Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «__enter__- og __exit__-protokollen»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Python Academy-leksjonen?
Ja. Alle Python Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- with-setningen i dybden
- __enter__- og __exit__-protokollen
- contextlib: @contextmanager
- Praktiske mønstre for kontekstbehandlere