Async context managers управляют ресурсами в async коде — соединениями, файлами, транзакциями.
aenter и aexit
class AsyncDB:
async def __aenter__(self):
self.conn = await connect("postgresql://localhost/mydb")
return self.conn
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.conn.close()
return False # не подавляем исключения
async def main():
async with AsyncDB() as conn:
result = await conn.fetch("SELECT * FROM users")
@asynccontextmanager — проще чем класс
from contextlib import asynccontextmanager
import httpx
@asynccontextmanager
async def managed_client(base_url: str):
client = httpx.AsyncClient(base_url=base_url, timeout=30.0)
try:
yield client
finally:
await client.aclose()
async def main():
async with managed_client("https://api.example.com") as client:
r = await client.get("/users")
aiofiles — async работа с файлами
import aiofiles
async def save_result(filename: str, data: str):
async with aiofiles.open(filename, "w", encoding="utf-8") as f:
await f.write(data)
async def read_file(filename: str) -> str:
async with aiofiles.open(filename, "r", encoding="utf-8") as f:
return await f.read()
# Обработка по строкам — не грузим всё в память
async def process_large_file(filename: str):
async with aiofiles.open(filename) as f:
async for line in f:
await process_line(line.strip())
Вложенные context managers
async def main():
async with (
httpx.AsyncClient() as client,
aiofiles.open("results.json", "w") as f,
):
for url in urls:
data = await client.get(url)
await f.write(data.text + "\n")
Python 3.10+ поддерживает скобочный синтаксис для нескольких async with — без бэкслешей.
Паттерн: async context manager для транзакций
@asynccontextmanager
async def transaction(conn):
await conn.execute("BEGIN")
try:
yield conn
await conn.execute("COMMIT")
except Exception:
await conn.execute("ROLLBACK")
raise
💬 Комментарии (0)
Комментариев пока нет
Станьте первым, кто поделится мнением об этой статье!