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

[PYTHON] Protocol (PEP 544)을 이용한 구조적 타이핑 구현 방법과 명시적 상속의 3가지 차이점 해결

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

Protocol (PEP 544)
Protocol (PEP 544)

파이썬은 전통적으로 '덕 타이핑(Duck Typing)'의 언어였습니다. "오리처럼 걷고 오리처럼 운다면 그것은 오리다"라는 철학은 유연한 개발을 가능하게 했지만, 대규모 프로젝트에서는 정적 분석의 어려움이라는 문제를 야기했습니다. 이를 해결하기 위해 등장한 것이 바로 PEP 544의 Protocol입니다. 본 글에서는 전문가의 시각에서 구조적 타이핑(Structural Typing)을 구현하는 구체적인 방법과 기존 추상 베이스 클래스(ABC)와의 결정적 차이를 분석합니다.


1. 구조적 타이핑(Structural Typing)이란 무엇인가?

일반적인 자바나 C#의 인터페이스는 '명시적 타이핑(Nominal Typing)'을 따릅니다. 즉, 클래스가 특정 인터페이스를 구현한다고 선언해야만 해당 타입으로 인정받습니다. 반면, 파이썬의 typing.Protocol은 클래스가 특정 메서드나 속성을 가지고 있기만 하면 별도의 상속 선언 없이도 해당 타입으로 간주합니다.

이 방식은 코드 간의 결합도를 낮추면서도 mypy와 같은 정적 검사 도구를 통해 타입 안정성을 확보할 수 있는 '해결'책이 됩니다.

2. Protocol vs ABC: 구현 방식의 3가지 핵심 차이

많은 개발자가 abc.ABCtyping.Protocol 사이에서 혼란을 겪습니다. 두 방식의 기술적 차이를 명확히 이해하는 것이 중요합니다.

비교 항목 명시적 타이핑 (ABC) 구조적 타이핑 (Protocol)
상속 관계 반드시 부모 클래스를 상속해야 함 상속 없이 메서드 일치만으로 성립
런타임 체크 isinstance() 체크 시 상속 계층 확인 @runtime_checkable 사용 시 속성 확인
유연성 서드파티 라이브러리 수정이 어려움 외부 라이브러리 객체에도 즉시 적용 가능
정적 분석 상속 관계를 기반으로 검사 메서드 시그니처 일치 여부로 검사

3. 실전 Sample Example: Protocol 구현 방법

다음은 현대적인 파이썬 환경에서 Protocol을 사용하여 다양한 형태의 저장소 객체를 동일한 타입으로 처리하는 해결 방법 예제입니다.


from typing import Protocol, runtime_checkable

@runtime_checkable
class Document(Protocol):
    """문서 객체가 갖춰야 할 구조 정의"""
    title: str
    def save(self) -> str:
        ...

class PDFFile:
    def __init__(self, title: str):
        self.title = title
    
    def save(self) -> str:
        return f"PDF '{self.title}' 저장 완료"

class WordFile:
    def __init__(self, title: str):
        self.title = title
    
    def save(self) -> str:
        return f"Word '{self.title}' 저장 완료"

def process_document(doc: Document):
    """Document 프로토콜을 준수하는 어떤 객체든 수용 가능"""
    print(doc.save())

# 사용 예시
pdf = PDFFile("Python_Guide")
word = WordFile("Note_2026")

process_document(pdf)  # 상속 관계가 없어도 정상 작동
process_document(word) # Duck Typing의 정적 버전

위 코드에서 PDFFileWordFileDocument를 상속받지 않았음에도 불구하고, save 메서드와 title 속성을 가졌기에 Document 타입으로 인정받습니다.

4. @runtime_checkable을 통한 런타임 문제 해결

기본적으로 Protocol은 정적 검사 시에만 유효합니다. 하지만 isinstance()를 통해 실행 시점에도 해당 타입을 검증하고 싶다면 @runtime_checkable 데코레이터를 사용해야 합니다. 이는 런타임에 객체의 메서드 존재 여부를 검사하는 로직을 자동으로 주입하여 안정성을 높여줍니다.

5. 결론: 왜 Protocol을 사용해야 하는가?

PEP 544의 도입은 파이썬을 진정한 '점진적 타이핑(Gradual Typing)' 언어로 완성시켰습니다. 클래스 계층 구조를 복잡하게 설계하지 않고도 필요한 기능을 인터페이스화할 수 있는 Protocol은 특히 대규모 시스템의 리팩토링과 테스트 코드 작성 시 강력한 힘을 발휘합니다. 코드의 유연성과 안정성이라는 두 마리 토끼를 잡고 싶다면 지금 즉시 Protocol 기반의 설계를 도입해 보시기 바랍니다.


내용의 출처 및 전문 지식 근거

  • Python Enhancement Proposals: PEP 544 - "Protocols: Structural subtyping"
  • Python standard library documentation: "typing — Support for type hints"
  • "Robust Python: Write Clean, Maintainable Code" by Patrick Viafore
728x90