본문으로 건너뛰기

Modern Typing

요즘 Python 회사에서 typing은 선택사항이 아니라 기본 전제인 경우가 많다. 특히 3.10 이후 문법 개선 덕분에 typing은 더 이상 장황한 보조 문법이 아니라, 코드 자체를 읽기 좋게 만드는 설계 도구가 되었다.

빠른 요약: 현대 Python typing의 핵심은 `X | Y`, `type` alias, `Annotated`, `Literal`, `Self`, `Never`, built-in generic syntax처럼 "코드 모양 자체를 더 읽기 좋게 만드는 도구"들이다.

빠르게 보는 핵심 문법

기능왜 중요한가예시
`XY`Union[X, Y]보다 훨씬 읽기 좋다
type aliasalias 선언 의도를 더 분명히 드러낸다type UserId = int
Annotated타입과 metadata를 한 자리에 둔다Annotated[int, Query(gt=0)]
Literal허용 값 집합을 명시한다Literal["draft", "published"]
Selffluent API와 classmethod return을 깔끔하게 만든다def with_name(self, ...) -> Self
Never도달 불가능한 흐름이나 종료 함수 시그니처를 표현한다def fail() -> Never
built-in genericslist[int] 같은 표기가 기본이 됐다dict[str, int]

실전 예제

py
from typing import Annotated, Literal, Never, Self


type UserId = int
type Status = Literal["draft", "published"]


class Article:
    def __init__(self, title: str, status: Status = "draft") -> None:
        self.title = title
        self.status = status

    def publish(self) -> Self:
        self.status = "published"
        return self


def fail(message: str) -> Never:
    raise RuntimeError(message)


PageSize = Annotated[int, "1..100 constraint lives here"]

Annotated는 타입과 metadata의 만남이다

  • 타입 체커는 주로 앞의 타입 부분을 본다.
  • FastAPI, Pydantic 같은 프레임워크는 뒤의 metadata도 소비할 수 있다.
  • 그래서 Annotated는 "정적 타입"과 "런타임 소비 정보"가 만나는 중요한 접점이다.

alias를 언제 두는 게 좋은가

도메인 의미가 생길 때

`UserId`, `OrderNumber`, `Slug`처럼 단순 타입보다 의미가 중요한 경우 alias가 가독성을 높인다.

복잡한 union을 반복할 때

여러 곳에서 쓰는 긴 type expression은 alias로 빼는 편이 API 문맥을 더 잘 드러낸다.

metadata까지 재사용할 때

`Annotated` alias로 validation metadata와 타입을 함께 재사용할 수 있다.

너무 이른 alias는 피한다

한 번만 쓰는 단순 타입까지 alias로 감싸면 오히려 읽기 어려워진다.

공식 자료

VitePress로 빌드한 Python 3.14 핸드북