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

[PYTHON] 인터페이스 규약 강제를 위한 NotImplementedError 활용 방법 3가지와 구조적 차이점

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

NotImplementedError 활용
NotImplementedError 활용

 

 

파이썬의 동적 특성 속에서도 엄격한 설계 규약을 유지하는 비결, NotImplementedError와 추상화 기법을 실무 관점에서 완벽히 정리합니다.


1. 개요: 왜 인터페이스 규약이 필요한가?

파이썬은 "덕 타이핑(Duck Typing)"을 지향하는 언어입니다. 하지만 대규모 프로젝트나 협업 환경에서는 특정 메서드가 반드시 구현되어야 함을 명시적으로 강제해야 할 때가 있습니다. 만약 자식 클래스가 부모 클래스에서 정의한 핵심 로직을 구현하지 않은 채 호출된다면, 런타임에 예상치 못한 버그가 발생할 수 있습니다. 이러한 문제를 방지하기 위해 파이썬 개발자들은 NotImplementedError를 던지거나 abc 모듈의 @abstractmethod를 사용합니다. 본 글에서는 이 두 방식의 차이를 해결하고, 실무에서 인터페이스 규약을 완벽하게 강제하는 7가지 이상의 Sample Example을 통해 가치 있는 아키텍처 설계법을 제안합니다.

2. NotImplementedError vs @abstractmethod: 핵심 차이 분석

규약을 강제하는 두 가지 주요 접근 방식의 차이점을 표로 정리하였습니다.

비교 항목 NotImplementedError (런타임 체크) ABC @abstractmethod (인스턴스화 체크)
강제 시점 해당 메서드가 실제로 호출되는 순간 클래스가 인스턴스화되는 순간 (객체 생성 시)
구현 유연성 높음 (일부 메서드만 선택적 구현 가능) 낮음 (모든 추상 메서드를 구현해야 객체 생성 가능)
에러 메시지 개발자가 직접 정의 가능 파이썬 인터프리터가 표준 에러 발생
해결 방법 부모 메서드 내에 raise 문 작성 ABC 상속 및 데코레이터 사용
적합한 상황 플러그인 구조나 느슨한 규약이 필요할 때 엄격한 프레임워크나 라이브러리 설계 시

3. 실무 적용을 위한 7가지 해결 Sample Examples

개발자가 실무 환경에서 바로 복사하여 적용할 수 있는 인터페이스 강제 사례들입니다.

Example 1: 데이터 저장소 인터페이스 (표준 활용)

모든 데이터베이스 처리 클래스가 반드시 가져야 할 기본 동작을 규정합니다.


class StorageInterface:
    def save(self, data):
        raise NotImplementedError("자식 클래스에서 'save' 메서드를 반드시 구현해야 합니다.")

    def delete(self, item_id):
        raise NotImplementedError("자식 클래스에서 'delete' 메서드를 반드시 구현해야 합니다.")

class CloudStorage(StorageInterface):
    def save(self, data):
        print(f"Cloud에 {data} 저장 완료")
    # delete를 구현하지 않고 호출하면 에러 발생
        

Example 2: 메시지 브로커 플러그인 (동적 로딩 대응)

동적으로 로딩되는 플러그인들이 규약을 지키는지 런타임에 확인합니다.


class MessageBroker:
    def publish(self, topic, message):
        raise NotImplementedError("Broker must implement publish method.")

class KafkaBroker(MessageBroker):
    def publish(self, topic, message):
        # Kafka 전송 로직
        pass
        

Example 3: 템플릿 메서드 패턴과의 결합

전체적인 흐름은 부모가 제어하되, 세부 단계 구현을 자식에게 위임합니다.


class ReportGenerator:
    def generate(self):
        data = self._fetch_data()  # 강제됨
        return f"Report: {data}"

    def _fetch_data(self):
        raise NotImplementedError("데이터 수집 로직을 구현하세요.")
        

Example 4: 다중 상속 및 믹스인(Mixin)에서의 활용

특정 기능을 제공하는 믹스인이 대상 클래스의 속성을 요구할 때 사용합니다.


class JSONSerializableMixin:
    def to_json(self):
        data = self._get_attributes()
        import json
        return json.dumps(data)

    def _get_attributes(self):
        raise NotImplementedError("Mixin requires _get_attributes implementation.")
        

Example 5: API 핸들러 규약 강제

HTTP 메서드별 처리 로직을 강제하여 누락된 엔드포인트를 방지합니다.


class BaseHandler:
    def handle_get(self, request):
        raise NotImplementedError("GET 요청 처리가 정의되지 않았습니다.")

    def handle_post(self, request):
        raise NotImplementedError("POST 요청 처리가 정의되지 않았습니다.")
        

Example 6: 머신러닝 모델 학습 인터페이스

새로운 알고리즘 추가 시 fitpredict가 누락되지 않도록 합니다.


class BaseModel:
    def fit(self, x, y):
        raise NotImplementedError("Training logic (fit) is missing.")

    def predict(self, x):
        raise NotImplementedError("Prediction logic (predict) is missing.")
        

Example 7: 커스텀 예외 메시지를 포함한 인터페이스

단순 에러가 아닌, 해결 방법을 가이드하는 에러를 던집니다.


class FileProcessor:
    def process(self):
        msg = f"'{self.__class__.__name__}' 클래스에 process()를 구현하거나 소스 경로를 확인하세요."
        raise NotImplementedError(msg)
        

4. 독창적인 아키텍처 가이드: 믹스인과 ABC의 하이브리드 전략

단순히 NotImplementedError만 사용하는 것보다, 현대적인 파이썬 설계에서는 ABC와 결합하는 것이 더 가치 있습니다. 인스턴스화 시점에는 ABC로 막고, 믹스인처럼 유연하게 주입되는 기능에는 NotImplementedError를 사용하여 런타임 안정성을 확보하는 해결 전략이 실무적으로 가장 뛰어납니다.

5. 결론: 견고한 파이썬 코드를 위한 제언

인터페이스는 단순한 제약이 아니라, 개발자 간의 약속입니다. NotImplementedError를 적재적소에 배치함으로써 팀원들에게 명확한 가이드를 제공하고, 시스템의 확장성을 안전하게 보장할 수 있습니다. 상속 구조를 설계할 때 "어떤 시점에 에러를 발견할 것인가?"를 고민하고 위 예제들을 활용해 보세요.


내용 출처 및 참고 자료:

  • Python Software Foundation - "Built-in Exceptions: NotImplementedError"
  • PEP 3119 – "Introducing Abstract Base Classes"
  • Effective Python: 90 Specific Ways to Write Better Python
  • Fluent Python (Luciano Ramalho) - Abstract Base Classes Chapter
728x90