반응형

Python의 TypedDict는 딕셔너리의 키와 값에 대한 타입을 명확하게 지정할 수 있게 해주는 기능입니다. 특히 복잡한 데이터 구조를 다룰 때 발생할 수 있는 타입 관련 오류를 미리 방지할 수 있어 유용합니다.

TypedDict가 필요한 이유

기존 딕셔너리는 이런 문제가 있었습니다.

# 일반 딕셔너리 사용 시
user = {
    "name": "김철수",
    "age": 25,
    "email": "kim@example.com"
}

# 흔히 발생하는 실수들
print(user["Name"])  # KeyError: 'Name' (키 이름 오타)
print(user["age"] + "살")  # TypeError: int + str 연산 불가
user["phone"] = 123  # 예상치 못한 새로운 키 추가

TypedDict 기본 사용법

1. 클래스 스타일로 선언하기

from typing import TypedDict

class User(TypedDict):
    name: str
    age: int
    email: str

# 타입 힌트가 있는 딕셔너리
user: User = {
    "name": "김철수",
    "age": 25,
    "email": "kim@example.com"
}

2. 함수형 스타일로 선언하기

from typing import TypedDict

# 대체 문법 사용
Movie = TypedDict('Movie', {
    'title': str,
    'director': str,
    'year': int,
    'rating': float
})

movie: Movie = {
    "title": "기생충",
    "director": "봉준호",
    "year": 2019,
    "rating": 4.5
}

TypedDict의 고급 기능

1. 필수/선택적 필드 지정

class BookBase(TypedDict):
    title: str    # 필수 필드
    author: str   # 필수 필드

class Book(BookBase, total=False):
    isbn: str        # 선택적 필드
    description: str # 선택적 필드

# description이 없어도 타입 에러가 발생하지 않습니다
book: Book = {
    "title": "파이썬 프로그래밍",
    "author": "홍길동",
    "isbn": "123-456-789"
}

2. TypedDict 상속

class MediaContent(TypedDict):
    title: str
    year: int

class Movie(MediaContent):
    director: str
    duration: int

class Series(MediaContent):
    seasons: int
    episodes_per_season: int

3. Extra Items와 Closed TypedDict

# 추가 필드의 타입을 제한하는 경우
class TaggedMovie(TypedDict, extra_items=bool):
    title: str
    year: int
    # 추가되는 모든 키의 값은 bool 타입이어야 함

# 추가 필드를 완전히 금지하는 경우
class StrictMovie(TypedDict, closed=True):
    title: str
    year: int
    # 정의되지 않은 필드는 추가할 수 없음

실전 예제: 복잡한 API 응답 처리

from typing import TypedDict, List, Optional

class GeoLocation(TypedDict):
    latitude: float
    longitude: float

class Address(TypedDict):
    street: str
    city: str
    country: str
    postal_code: str
    geo: GeoLocation

class UserProfile(TypedDict, total=False):
    id: int
    username: str
    email: str
    addresses: List[Address]
    phone: Optional[str]
    is_active: bool

# API 응답 데이터
user_data: UserProfile = {
    "id": 1,
    "username": "python_lover",
    "email": "python@example.com",
    "addresses": [{
        "street": "강남대로 123",
        "city": "서울",
        "country": "대한민국",
        "postal_code": "06000",
        "geo": {
            "latitude": 37.5665,
            "longitude": 126.9780
        }
    }],
    "is_active": True
}

TypedDict 사용 시 주의사항

  1. 런타임 검사 없음: TypedDict는 정적 타입 검사 도구(mypy 등)에서만 작동합니다.
    • # 런타임에서는 이런 오류를 잡지 못합니다 movie: Movie = {"title": 123} # 타입 힌트 위반이지만 실행은 됨
  2. IDE 지원: PyCharm, VS Code 등 현대적인 IDE에서 타입 검사와 자동완성을 지원합니다.
  3. Python 버전 호환성: Python 3.8 이상에서 모든 기능을 사용할 수 있습니다.

TypedDict를 효과적으로 사용하는 경우

  1. API 통신: 외부 API의 요청/응답 데이터 구조 정의
  2. 설정 파일: 프로그램의 설정 데이터 구조 정의
  3. 데이터베이스: ORM 모델의 필드 타입 정의
  4. 테스트: 목업 데이터의 구조 정의

TypedDict는 특히 큰 프로젝트에서 데이터 구조를 명확하게 정의하고, 타입 관련 버그를 미리 방지하는 데 매우 유용합니다. 정적 타입 검사 도구와 함께 사용하면 더욱 효과적입니다.

반응형