__enter__- ja __exit__-protokolla
Rakentakaa kontekstinhallitsijoita dunder-protokollan avulla.
__enter__- ja __exit__-protokolla on ilmainen Python Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Python Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Python Academy-kurssilla on yhteensä 4 oppituntia.
Kontekstinhallintaprotokolla
Kaikki oliot, jotka määrittelevät __enter__- ja __exit__-metodit, ovat kontekstinhallintaolioita ja niitä voidaan käyttää with-lausekkeiden kanssa.
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")__enter__-metodin palautusarvo
__enter__ kutsutaan with-lohkon alussa. Sen palautusarvo sidotaan muuttujaan, joka tulee as-sanan jälkeen.
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__exit__-metodin argumentit
__exit__(exc_type, exc_val, exc_tb) vastaanottaa poikkeustiedot, jos tapahtui virhe. Jos poikkeusta ei tapahtunut, kaikki kolme arvoa ovat 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") # suppressedPoikkeusten vaientaminen
Palauttakaa True metodista __exit__, jos haluatte vaientaa poikkeuksen. Palauttakaa False tai älkää palauttako mitään, jos haluatte sen välittyvän eteenpäin.
class Ignore:
def __enter__(self): return self
def __exit__(self, *args): return True # swallow all exceptions
with Ignore():
1 / 0
print("continues here")Esimerkki tietokantayhteydestä
Klassinen käyttötapaus: hankkikaa yhteys enter-vaiheessa, vahvistakaa muutokset tai perukaa ne ja sulkekaa yhteys exit-vaiheessa.
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 FalseAjastinkontekstinhallintaolio
Mit atkaa kulunut aika tallentamalla aloitushetki __enter__-metodissa ja laskemalla erotus __exit__-metodissa.
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))Kontekstinhallintaolioiden sisäkkäisyys
Useita kontekstinhallintaolioita voidaan yhdistää yhdelle with-riville.
with open("in.txt") as src, open("out.txt", "w") as dst:
dst.write(src.read())Uudelleenkäytettävät ja kertakäyttöiset hallintaoliot
Kontekstinhallintaoliot, joiden __enter__ varaa joka kerta uuden resurssin, ovat uudelleenkäytettäviä. Oliot, joiden sisäinen tila kuluu loppuun — kuten vain kerran pidettävä lukko — eivät välttämättä ole uudelleenkäytettäviä.
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__ ja __aexit__ (asynkroninen)
Asynkronisia kontekstinhallintaolioita varten määritelkää __aenter__- ja __aexit__-korutiinit ja käyttäkää async with-lausetta.
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:
# ...Tiedosto-olioiden kääriminen
Pythonin tiedosto-oliot toteuttavat jo kontekstinhallintaprotokollan — älkää koskaan kutsuko f.close()-metodia manuaalisesti.
with open("data.txt", "r") as f:
data = f.read()
# file is closed here automatically
print(f.closed) # TrueLukon toteuttaminen
Säielukot ovat kontekstinhallintaolioita: __enter__ hankkii lukon ja __exit__ vapauttaa sen.
import threading
lock = threading.Lock()
def update_shared():
with lock:
# critical section
passPikatarkistus
Mitä __exit__-metodin pitäisi palauttaa poikkeuksen vaimentamiseksi?
Kertaus
Toteuttakaa __enter__- ja __exit__-metodit kontekstinhallintojen luomiseksi. Palauttakaa resurssi metodista __enter__ ja huolehtikaa metodissa __exit__ siivouksesta sekä poikkeusten vaimentamisesta.
Opi Python tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 76
- Oppitunnit
- 320
Usein kysytyt kysymykset
Onko oppitunti ”__enter__- ja __exit__-protokolla” ilmainen?
Kyllä – oppitunnin ”__enter__- ja __exit__-protokolla” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Python Academy-kurssin, päivitä CoddyKit PROhon. Python Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”__enter__- ja __exit__-protokolla”?
Rakentakaa kontekstinhallitsijoita dunder-protokollan avulla. Harjoittelet Python Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Python Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Python Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”__enter__- ja __exit__-protokolla”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Python Academy-oppitunnilla?
Kyllä. Jokainen Python Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- with-lauseen perusteet
- __enter__- ja __exit__-protokolla
- contextlib: @contextmanager
- Käytännön kontekstinhallitsijamallit