PHpullh
학습 라이브러리/Python/Context Variables & 의존성 주입

PYTHON · 디자인패턴

Context Variables & 의존성 주입

의존성 주입 패턴과 contextvars로 스레드/코루틴 안전한 컨텍스트를 관리합니다.

디자인패턴중급ContextVar의존성주입DIcontainerasyncio

핵심 설명

의존성 주입 패턴과 contextvars로 스레드/코루틴 안전한 컨텍스트를 관리합니다.

Python code

from contextvars import ContextVar
from typing import Optional
import asyncio

# ContextVar — 코루틴/스레드마다 독립적인 값
current_user: ContextVar[Optional[str]] = ContextVar(
    "current_user", default=None
)
request_id: ContextVar[str] = ContextVar("request_id")

async def handle_request(user: str, req_id: str):
    current_user.set(user)
    request_id.set(req_id)
    await process()

async def process():
    user = current_user.get()
    rid  = request_id.get()
    print(f"[{rid}] {user} 처리 중")
    await asyncio.sleep(0.01)

# 의존성 주입 — 간단한 컨테이너
class Container:
    _services = {}

    @classmethod
    def register(cls, name: str, factory):
        cls._services[name] = factory

    @classmethod
    def resolve(cls, name: str):
        return cls._services[name]()

# 등록
Container.register("db", lambda: {"connected": True})
Container.register("cache", lambda: {})

# 사용
db    = Container.resolve("db")
cache = Container.resolve("cache")

async def main():
    await asyncio.gather(
        handle_request("Alice", "req-001"),
        handle_request("Bob",   "req-002"),
    )

asyncio.run(main())

학습 팁

ContextVar는 Python 3.7+에서 사용 가능합니다. 비동기 코드에서 스레드 로컬 변수처럼 사용하되 코루틴 간 격리가 보장됩니다.

주의할 점

threading.local()은 스레드 안전하지만 asyncio 코루틴 간에 값이 공유될 수 있습니다. 비동기 코드에서는 반드시 ContextVar를 사용하세요.

자주 묻는 질문

Context Variables & 의존성 주입란 무엇인가요?

의존성 주입 패턴과 contextvars 로 스레드/코루틴 안전한 컨텍스트를 관리합니다.

Context Variables & 의존성 주입 학습 시 주의할 점은 무엇인가요?

threading.local() 은 스레드 안전하지만 asyncio 코루틴 간에 값이 공유될 수 있습니다. 비동기 코드에서는 반드시 ContextVar 를 사용하세요.