Asynkrona kontexthanterare och iteratorer
Implementera protokollen async with och async for.
Asynkrona kontexthanterare och iteratorer är en gratis lektion i Python Academy på CoddyKit. Detta är lektion 3 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.
Satsen async with
Använd async with för kontexthanterare vars initiering eller avslutning innebär att I/O måste inväntas. Det hanterade objektet måste implementera __aenter__ och __aexit__.
import asyncio
class AsyncFile:
async def __aenter__(self):
print("open")
return self
async def __aexit__(self, *args):
print("close")
async def main():
async with AsyncFile() as f:
print("using")
asyncio.run(main())__aenter__ och __aexit__
Båda är coroutine-funktioner. __aenter__ inväntas vid inträde och __aexit__ inväntas vid utträde, även om ett undantag har inträffat.
import asyncio
class DBSession:
async def __aenter__(self):
self.conn = await async_connect()
return self.conn
async def __aexit__(self, exc_type, exc_val, exc_tb):
if exc_type:
await self.conn.rollback()
else:
await self.conn.commit()
await self.conn.close()
return False@asynccontextmanager
contextlib.asynccontextmanager låter dig skriva asynkrona kontexthanterare som asynkrona generatorfunktioner.
from contextlib import asynccontextmanager
import asyncio
@asynccontextmanager
async def managed_resource():
print("acquire")
try:
yield {"status": "ready"}
finally:
print("release")
async def main():
async with managed_resource() as r:
print(r["status"])
asyncio.run(main())Satsen async for
async for itererar över ett asynkront itererbart objekt – ett objekt som implementerar __aiter__ och __anext__. Varje iteration kan innebära I/O.
import asyncio
class AsyncCounter:
def __init__(self, n): self.n, self.i = n, 0
def __aiter__(self): return self
async def __anext__(self):
if self.i >= self.n: raise StopAsyncIteration
await asyncio.sleep(0)
self.i += 1
return self.i
async def main():
async for val in AsyncCounter(3):
print(val)
asyncio.run(main())Asynkrona generatorer
En async def-funktion som innehåller yield är en asynkron generator. Använd async for för att läsa från den.
import asyncio
async def ticker(n):
for i in range(n):
await asyncio.sleep(1)
yield i
async def main():
async for val in ticker(3):
print(val) # 0, 1, 2 with 1-s pauses
asyncio.run(main())aiofiles för asynkron fil-I/O
Biblioteket aiofiles kapslar in filoperationer i asynkrona kontexthanterare och asynkrona iteratorer.
# pip install aiofiles
import aiofiles, asyncio
async def main():
async with aiofiles.open("data.txt", "r") as f:
async for line in f:
print(line.strip())aiohttp-klientsession
aiohttp.ClientSession är en asynkron kontexthanterare för att göra samtidiga HTTP-förfrågningar.
# pip install aiohttp
import aiohttp, asyncio
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
return await resp.json()
asyncio.run(fetch("https://api.example.com/data"))Flera asynkrona kontexthanterare
Placera flera async with-satser på samma rad, med den parentesform som stöds från och med Python 3.10.
import asyncio
async def main():
async with (
open_db() as db,
open_cache() as cache,
):
data = await db.fetch("SELECT 1")
await cache.set("key", data)AsyncExitStack
contextlib.AsyncExitStack hanterar en dynamisk uppsättning asynkrona kontexthanterare.
from contextlib import AsyncExitStack
import asyncio
async def main():
async with AsyncExitStack() as stack:
conn1 = await stack.enter_async_context(connect("db1"))
conn2 = await stack.enter_async_context(connect("db2"))
await process(conn1, conn2)Testa asynkron kod med pytest-asyncio
pytest-asyncio låter dig skriva asynkrona testfunktioner med markören @pytest.mark.asyncio.
# pip install pytest-asyncio
import pytest, asyncio
async def fetch(): return 42
@pytest.mark.asyncio
async def test_fetch():
result = await fetch()
assert result == 42Sammanfattning av protokollet för asynkrona iteratorer
Ett objekt är asynkront itererbart om det har __aiter__. Det är en asynkron iterator om det dessutom har __anext__. Asynkrona generatorer implementerar automatiskt båda.
import asyncio
async def gen():
yield 1
yield 2
async def main():
g = gen()
print(await g.__anext__()) # 1
print(await g.__anext__()) # 2Snabb kontroll
Vilka dunder-metoder måste ett objekt implementera för att kunna användas med async with?
Sammanfattning
Använd async with för resurser som behöver asynkron initiering eller avslutning. Använd async for för itererbara objekt som producerar värden asynkront. Asynkrona generatorer förenklar skapandet av asynkrona iteratorer. Bibliotek som aiofiles och aiohttp tillhandahåller fil- och HTTP-operationer med inbyggt stöd för async.
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 ”Asynkrona kontexthanterare och iteratorer” gratis?
Ja – hela texten till ”Asynkrona kontexthanterare och iteratorer” 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 ”Asynkrona kontexthanterare och iteratorer”?
Implementera protokollen async with och async for. 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 3 av 4.
Hur lång tid tar lektionen ”Asynkrona kontexthanterare och iteratorer”?
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
- Korutiner och händelseslingan
- await, tasks och gathering
- Asynkrona kontexthanterare och iteratorer
- Mönster för asynkron I/O i produktion