PHpullh
학습 라이브러리/Python/async 컨텍스트 매니저 & 이터레이터

PYTHON · 비동기

async 컨텍스트 매니저 & 이터레이터

async withasync for로 비동기 리소스를 안전하게 관리합니다.

비동기고급async-with__aenter____aexit__asynccontextmanagerasync-for

핵심 설명

async withasync for로 비동기 리소스를 안전하게 관리합니다.

Python code

import asyncio
from contextlib import asynccontextmanager

# async context manager
class AsyncDB:
    async def __aenter__(self):
        print("DB 연결")
        await asyncio.sleep(0.1)
        return self

    async def __aexit__(self, *args):
        print("DB 연결 해제")
        await asyncio.sleep(0.05)

    async def query(self, sql: str) -> list:
        await asyncio.sleep(0.1)
        return [{"id": 1, "name": "Alice"}]

# @asynccontextmanager 데코레이터 방식
@asynccontextmanager
async def managed_connection(url: str):
    print(f"연결: {url}")
    connection = {"url": url, "open": True}
    try:
        yield connection
    finally:
        connection["open"] = False
        print(f"해제: {url}")

# async generator — async for 사용
async def paginate(total: int, page_size: int = 10):
    for page in range(0, total, page_size):
        await asyncio.sleep(0.01)   # DB 조회 시뮬레이션
        yield list(range(page, min(page + page_size, total)))

async def main():
    async with AsyncDB() as db:
        rows = await db.query("SELECT * FROM users")
        print(rows)

    async with managed_connection("postgres://localhost") as conn:
        print(f"연결 상태: {conn['open']}")

    # async for
    async for page in paginate(35):
        print(f"페이지: {page}")

asyncio.run(main())

학습 팁

@asynccontextmanagerasync with를 지원하는 컨텍스트 매니저를 제너레이터로 간단하게 만들 수 있습니다.

주의할 점

일반 for 루프로 async generator를 순회할 수 없습니다. 반드시 async for를 사용해야 합니다.

자주 묻는 질문

async 컨텍스트 매니저 & 이터레이터란 무엇인가요?

async with 와 async for 로 비동기 리소스를 안전하게 관리합니다.

async 컨텍스트 매니저 & 이터레이터 학습 시 주의할 점은 무엇인가요?

일반 for 루프로 async generator를 순회할 수 없습니다. 반드시 async for 를 사용해야 합니다.