Python Academy · Lektion

Asynkrone context managers og iteratorer

Implementér protokollerne async with og async for.

Lektion 3 af 413 trin

Asynkrone context managers og iteratorer er en gratis Python Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Python Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Python Academy-kurset indeholder 4 lektioner i alt.

Sætningen async with

Brug async with til kontekstmanagere, hvis opsætning og oprydning involverer afventning af I/O. Det administrerede objekt skal implementere __aenter__ og __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__ og __aexit__

Begge er coroutiner. __aenter__ afventes ved indtrædelse, og __aexit__ afventes ved afslutning, også hvis der opstod en undtagelse.

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 lader dig skrive asynkrone kontekstmanagere som asynkrone 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())

Sætningen async for

async for gennemløber en asynkron itererbar — en, der implementerer __aiter__ og __anext__. Hver gennemløbning kan involvere 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())

Asynkrone generatorer

En async def-funktion, der indeholder yield, er en asynkron generator. Brug async for til at gennemløbe 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 til asynkron fil-I/O

Biblioteket aiofiles omslutter filhandlinger i asynkrone kontekstmanagere og asynkrone 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 er en asynkron kontekstmanager til at sende samtidige HTTP-forespørgsler.

# 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"))

Flere asynkrone kontekstmanagere

Stak flere async with-sætninger på én linje i formen med parenteser, der blev introduceret i 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 administrerer et dynamisk sæt af asynkrone kontekstmanagere.

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)

Test af asynkron kode med pytest-asyncio

pytest-asyncio lader dig skrive asynkrone 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

Opsummering af protokollen for asynkrone iteratorer

Et objekt er asynkront itererbart, hvis det har __aiter__. Det er en asynkron iterator, hvis det også har __anext__. Asynkrone generatorer implementerer automatisk begge dele.

import asyncio

async def gen():
    yield 1
    yield 2

async def main():
    g = gen()
    print(await g.__anext__())   # 1
    print(await g.__anext__())   # 2

Hurtig test

Hvilke dunder-metoder skal et objekt implementere for at kunne bruges med async with?

Opsummering

Brug async with til ressourcer, der kræver asynkron opsætning og oprydning. Brug async for til itererbare objekter, der producerer værdier asynkront. Asynkrone generatorer forenkler oprettelsen af asynkrone iteratorer. Biblioteker som aiofiles og aiohttp leverer asynkrone fil- og HTTP-handlinger.

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
76
Lektioner
320

Ofte stillede spørgsmål

Er lektionen “Asynkrone context managers og iteratorer” gratis?

Ja — hele teksten til “Asynkrone context managers og iteratorer” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Python Academy-kurset, skal du opgradere til CoddyKit PRO. Python Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Asynkrone context managers og iteratorer”?

Implementér protokollerne async with og async for. Du øver dig i Python Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Python Academy?

Der kræves ingen tidligere erfaring. Python Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Asynkrone context managers og iteratorer”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Python Academy-lektion?

Ja. Alle Python Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Coroutiner og event loop
  2. await, tasks og indsamling
  3. Asynkrone context managers og iteratorer
  4. Mønstre for asynkron I/O i produktion
← Tilbage til Python Academy