📝 Python

Async context managers: async with и @asynccontextmanager

P
Автор
Pyland
📅
Опубликовано
30.06.2026
⏱️
Время чтения
1 мин
👁️
Просмотров
109
🌳
Уровень
Продвинутый
🐦 💼 ✈️

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)

🔐 Войдите в систему, чтобы оставить комментарий
🚪 Войти
💭

Комментариев пока нет

Станьте первым, кто поделится мнением об этой статье!

🔗 Похожие

Похожие статьи

Продолжите изучение с этими материалами

📝

Event loop в Python: как asyncio делает «параллел…

Event loop — сердце asyncio. Он не запускает код параллельно в нескольких потоках. Он переключается...

📅 30.06.2026 👁️ 123
📝

pytest-django: тестирование Django

Охватываемые темы: Установка, @pytest.mark.djangodb, Фикстуры, Тестирование views.

📅 30.06.2026 👁️ 132
📝

pip: менеджер пакетов Python

Охватываемые темы: Установка пакетов, Обновление и удаление, requirements.txt, Виртуальное окружение.

📅 30.06.2026 👁️ 120

Понравилась статья?

Подпишитесь на наши обновления и получайте новые статьи первыми. Развивайтесь вместе с PyLand!