본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] 의존성 주입(DI) 프레임워크 도입 여부 결정을 위한 3가지 판단 기준과 해결 방법

by Papa Martino V 2026. 3. 28.
728x90

의존성 주입(Dependency Injection, DI)
의존성 주입 (Dependency Injection, DI)

 

자바(Java)의 Spring이나 .NET 환경에서 넘어온 개발자들이 파이썬을 처음 접할 때 가장 당혹스러워하는 지점 중 하나가 바로 의존성 주입(Dependency Injection, DI)입니다. "파이썬처럼 유연한 동적 언어에서 굳이 복잡한 DI 프레임워크가 필요한가?"라는 의문은 커뮤니티 내에서도 오랜 논쟁거리입니다. 본 포스팅에서는 파이썬 특유의 덕 타이핑(Duck Typing)과 모듈 시스템이 DI 프레임워크와 어떤 차이를 보이는지 분석하고, 대규모 프로젝트에서 발생하는 결합도 문제를 해결하기 위한 최적의 아키텍처 설계 방법을 제시합니다.


1. 파이썬과 DI 프레임워크: 필요성 논란의 핵심

객체가 스스로 의존성을 생성하지 않고 외부에서 주입받는다는 DI의 핵심 원칙은 언어와 상관없이 유효합니다. 하지만 파이썬은 언어 자체가 가진 '동적 특성' 때문에 자바와 같은 정적 언어와는 접근 방식이 다릅니다.

DI 프레임워크 도입 여부에 따른 장단점 비교

비교 항목 프레임워크 미사용 (Manual DI) 프레임워크 사용 (Dependency Injector 등)
코드 복잡도 낮음 (단순 생성자 주입) 높음 (Container 설정 필요)
객체 생명주기 관리 수동 (Singleton 구현 번거로움) 자동 (Scope 관리 용이)
테스트 용이성 보통 (Mocking 라이브러리 의존) 매우 높음 (의존성 오버라이딩 가능)
런타임 오버헤드 없음 미세하게 존재 (Inspection 비용)

2. 파이썬에서 DI 프레임워크를 써야 하는 3가지 신호

모든 프로젝트에 프레임워크가 필요한 것은 아닙니다. 하지만 다음과 같은 상황이 발생한다면 프레임워크 도입이 코드의 질을 높이는 방법이 됩니다.

  • 객체 그래프의 복잡성: 서비스 A가 B를 필요로 하고, B가 C와 D를 필요로 하는 등 의존성 체인이 3단계 이상 깊어질 때.
  • 생명주기(Scope) 관리의 어려움: 요청(Request)마다 새로 생성되어야 하는 객체와 전역에서 하나만 존재해야 하는 싱글톤 객체가 혼재될 때.
  • 대규모 테스트 스위트 운영: 수천 개의 테스트 케이스에서 특정 DB 연결이나 API 클라이언트를 일관되게 Mock으로 교체해야 할 때.

3. [Sample Example] 프레임워크를 이용한 의존성 관리 해결

파이썬에서 가장 널리 쓰이는 dependency-injector 라이브러리를 활용하여 깔끔하게 의존성을 해결하는 예시입니다.


from dependency_injector import containers, providers

# 1. 의존성을 가질 클래스 정의
class ApiClient:
    def __init__(self, api_key: str):
        self.api_key = api_key

class UserService:
    def __init__(self, api_client: ApiClient):
        self.api_client = api_client

# 2. DI 컨테이너 선언
class Container(containers.DeclarativeContainer):
    config = providers.Configuration()
    
    # API 클라이언트를 싱글톤으로 관리
    api_client = providers.Singleton(
        ApiClient,
        api_key=config.api_key,
    )

    # UserService에 ApiClient 주입
    user_service = providers.Factory(
        UserService,
        api_client=api_client,
    )

# 3. 사용 방법
container = Container()
container.config.api_key.from_value("SECRET_KEY_123")
user_service = container.user_service()
        

4. 파이썬다운 DI를 위한 전문가의 조언

파이썬 개발자라면 프레임워크에 종속되기보다 '인터페이스''추상화'에 먼저 집중해야 합니다. 파이썬의 typing.Protocol이나 abc.ABC를 활용하여 클래스 간의 계약을 명확히 하면, 프레임워크 없이도 충분히 유연한 구조를 유지할 수 있습니다.

만약 FastAPI와 같은 현대적인 웹 프레임워크를 사용 중이라면, 자체적으로 내장된 Depends 시스템을 적극 활용하는 것이 가장 효율적인 방법입니다. 이는 외부 라이브러리 추가 없이도 강력한 DI 기능을 제공하기 때문입니다.


5. 결론

파이썬에서 DI 프레임워크는 선택의 문제입니다. 소규모 스크립트나 간단한 API에서는 Manual DI가 정답일 수 있지만, 수십 명의 개발자가 참여하는 거대 마이크로서비스 환경에서는 프레임워크가 제공하는 '강제성'과 '구조화'가 큰 힘을 발휘합니다. 오늘 소개한 3가지 기준을 통해 여러분의 프로젝트에 최적화된 아키텍처를 해결해 보시길 바랍니다.


내용 출처 및 참고 문헌

  • Python Dependency Injector Documentation: Main Concepts and Providers
  • Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern
  • FastAPI Docs: Dependency Injection Fundamentals
  • "Architecture Patterns with Python" (Harry Percival, Bob Gregory)
728x90