Python Academy · Lektion

Asynkrona kontexthanterare och iteratorer

Implementera protokollen async with och async for.

Lektion 3 av 413 steg

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 == 42

Sammanfattning 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__())   # 2

Snabb 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.

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 ”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

  1. Korutiner och händelseslingan
  2. await, tasks och gathering
  3. Asynkrona kontexthanterare och iteratorer
  4. Mönster för asynkron I/O i produktion
← Tillbaka till Python Academy