0Pricing
Python Academy · Lekcja

Asynchroniczne menedżery kontekstu i iteratory

Proszę implementować protokoły async with i async for.

Asynchroniczne menedżery kontekstu i iteratory to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.

Instrukcja async with

Proszę używać async with w przypadku menedżerów kontekstu, których konfiguracja lub sprzątanie wymaga oczekiwania na operacje wejścia-wyjścia. Zarządzany obiekt musi implementować __aenter__ i __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__ i __aexit__

Obie metody są korutynami. Metoda __aenter__ jest oczekiwana przy wejściu, a metoda __aexit__ przy wyjściu, nawet jeśli wystąpił wyjątek.

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 umożliwia pisanie asynchronicznych menedżerów kontekstu w postaci funkcji będących generatorami asynchronicznymi.

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())

Instrukcja async for

async for iteruje po obiekcie iterowalnym asynchronicznie — takim, który implementuje __aiter__ i __anext__. Każda iteracja może obejmować operacje wejścia-wyjścia.

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())

Generatory asynchroniczne

Funkcja async def zawierająca yield jest generatorem asynchronicznym. Proszę używać async for, aby pobierać z niego wartości.

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 do asynchronicznych operacji na plikach

Biblioteka aiofiles opakowuje operacje na plikach w asynchroniczne menedżery kontekstu i iteratory asynchroniczne.

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

Sesja klienta aiohttp

aiohttp.ClientSession jest asynchronicznym menedżerem kontekstu służącym do wykonywania współbieżnych żądań HTTP.

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

Wiele asynchronicznych menedżerów kontekstu

Proszę umieścić wiele klauzul async with w jednym wierszu, korzystając z formy nawiasowej dostępnej w Pythonie 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 zarządza dynamicznym zbiorem asynchronicznych menedżerów kontekstu.

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)

Testowanie kodu asynchronicznego za pomocą pytest-asyncio

pytest-asyncio umożliwia pisanie asynchronicznych funkcji testowych z użyciem znacznika @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

Podsumowanie protokołu iteratora asynchronicznego

Obiekt jest iterowalny asynchronicznie, jeśli ma metodę __aiter__. Jest iteratorem asynchronicznym, jeśli ma również metodę __anext__. Generatory asynchroniczne implementują obie metody automatycznie.

import asyncio

async def gen():
    yield 1
    yield 2

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

Szybki test

Jakie metody dunder musi implementować obiekt, aby można było używać go z async with?

Podsumowanie

Proszę używać async with w przypadku zasobów wymagających asynchronicznej konfiguracji lub sprzątania. Proszę używać async for w przypadku obiektów iterowalnych, które asynchronicznie dostarczają wartości. Generatory asynchroniczne upraszczają tworzenie iteratorów asynchronicznych. Biblioteki takie jak aiofiles i aiohttp udostępniają natywne dla kodu asynchronicznego operacje na plikach i żądania HTTP.

Często zadawane pytania

Czy lekcja „Asynchroniczne menedżery kontekstu i iteratory” jest bezpłatna?

Tak — pełny tekst „Asynchroniczne menedżery kontekstu i iteratory” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Asynchroniczne menedżery kontekstu i iteratory”?

Proszę implementować protokoły async with i async for. Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Python Academy?

Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Asynchroniczne menedżery kontekstu i iteratory”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?

Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Korutyny i pętla zdarzeń
  2. await, zadania i grupowanie
  3. Asynchroniczne menedżery kontekstu i iteratory
  4. Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym
← Powrót do Python Academy