C.W.K.
Stream
Lesson 03 of 05 · published

TypedDict — 타입 가진 구조화된 dict

~18 min · typeddict, structured-dict, notrequired

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

dict 모양 문제

구조화된 레코드 표현하는 dict — {"name": ..., "age": ..., "tags": [...]}. dict[str, Any] 타입 힌트는 유용한 거 안 알려줘. TypedDict 가 키와 타입 묘사 가능하게 — 체커가 사용 검증.

두 선언 스타일

클래스 스타일 — class User(TypedDict): name: str; age: int. 또는 함수형 — User = TypedDict("User", {"name": str, "age": int}). 클래스 스타일이 더 잘 읽힘, 함수형은 키가 유효 Python 식별자 X 일 때 (하이픈 가진 키 같은) 필요. 둘 다 런타임에 같은 타입 생성.

NotRequired 와 total=False

디폴트로 TypedDict 의 모든 필드 필수. 클래스 선언의 total=False 가 다 옵션. NotRequired[X] (3.11+) 가 특정 필드 옵션 표시 + 나머지 필수 유지. Required[X] 가 반대 — 그렇지 않으면 total=False 인 dict 의 필수 필드.

TypedDict 런타임 — 여전히 dict

TypedDict 가 런타임에 dict. isinstance(user, dict) 가 True. 타입 정보는 순수 정적 체크용. User(name=..., age=...) 를 검증하는 생성자처럼 호출 시도 X — 그냥 dict 만듦.

TypedDict vs dataclass vs Pydantic 선택

TypedDict — JSON 모양 데이터 + 타입 원할 때. Dataclass — 속성 가진 Python 클래스 원할 때 (obj.name, obj["name"] X). Pydantic — 런타임 검증 + 풍부한 필드 의미 필요할 때. Pippa 가 FastAPI 요청/응답 모델에 Pydantic 많이 사용.

Code

TypedDict — 클래스 스타일·python
from typing import TypedDict

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

def greet(u: User) -> str:
    return f"hi {u['name']} ({u['age']})"

u: User = {"name": "alice", "age": 30, "email": "a@x.com"}
print(greet(u))

# 런타임에 u 는 일반 dict
print(type(u))                         # <class 'dict'>
print(isinstance(u, dict))             # True
옵션 필드 — NotRequired (3.11+)·python
from typing import TypedDict, NotRequired

class User(TypedDict):
    name: str
    age: int
    nickname: NotRequired[str]            # 옵션
    bio: NotRequired[str]                 # 옵션

minimal: User = {"name": "alice", "age": 30}                       # OK
full: User = {"name": "bob", "age": 25, "nickname": "b", "bio": "hi"}

# 3.11 이전 — total=False 가 모든 거 옵션
class Settings(TypedDict, total=False):
    theme: str
    font: str
    debug: bool

s: Settings = {}                       # OK — 모든 필드 옵션
s2: Settings = {"theme": "dark"}      # OK
함수형 스타일 — 비-식별자 키용·python
from typing import TypedDict

# 가끔 API 응답이 유효 Python 이름 아닌 키 가짐
# 함수형 스타일이 처리
GoogleApiResponse = TypedDict("GoogleApiResponse", {
    "status": str,
    "error-code": int,         # 키에 하이픈 — 무효 식별자
    "User-Agent": str,         # 대문자와 하이픈
})

resp: GoogleApiResponse = {
    "status": "ok",
    "error-code": 0,
    "User-Agent": "...",
}
TypedDict vs dataclass — 모양 선택·python
from typing import TypedDict
from dataclasses import dataclass

# TypedDict — 체크된 구조 가진 dict 원할 때
class UserDict(TypedDict):
    name: str
    age: int

def use_dict(u: UserDict):
    print(u["name"])              # 대괄호 접근

# Dataclass — 속성 가진 클래스 원할 때
@dataclass
class UserClass:
    name: str
    age: int

def use_class(u: UserClass):
    print(u.name)                 # 속성 접근

# JSON in/out — TypedDict 가 wire 포맷에 더 가까움
# 도메인 로직 — dataclass 가 더 잘 읽힘

External links

Exercise

TypedDict Stock 정의 — 필수 필드 ticker: str, price: float, shares: int, NotRequired 필드 note: str, tags: list[str]. 함수 total_value(s: Stock) -> float 가 price * shares 반환. 여러 Stock dict (옵션 필드 일부 있고 일부 없게) 만들고 함수 호출. 머릿속으로 타입 체커 돌려서 mypy 행복한지 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.