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 == 42Podsumowanie 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__()) # 2Szybki 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
- Korutyny i pętla zdarzeń
- await, zadania i grupowanie
- Asynchroniczne menedżery kontekstu i iteratory
- Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym