dataclass는 class의 축소판이 아니라, 데이터 필드가 중심인 클래스를 짧게 쓰는 도구입니다.
일반 class를 먼저 본 뒤 읽으면 무엇을 자동으로 줄여 주는지, default_factory가 왜 중요한지 차이가 더 잘 보입니다.
핵심 정리
from dataclasses import dataclass, field
@dataclass
class User:
name: str
age: int
tags: list[str] = field(default_factory=list)문법
기본형은 @dataclass, 타입 힌트 필드, 필요하면 field(...)까지 함께 보면 됩니다.
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: intdataclass 선택
데이터 중심 클래스면 @dataclass
필드 저장이 핵심이고 복잡한 동작이 많지 않은 클래스는 __init__, __repr__, 비교 메서드를 반복해서 쓰기 쉽습니다.
@dataclass는 기본 설정에서 이런 보일러플레이트를 생성해 줍니다. 다만 eq=False, order=False, frozen=True 같은 옵션에 따라 생성되는 메서드와 동작은 달라집니다.
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int그래서 "상태 필드가 중심"인 객체라면 일반 클래스보다 dataclass가 더 간결합니다.
일반 class와의 경계는 "행동보다 데이터가 중심인가"
복잡한 불변식 관리, 풍부한 메서드, 커스텀 생성 규칙이 많다면 일반 클래스가 더 맞을 수 있습니다. 반대로 값 객체나 설정 구조체 같은 역할이면 dataclass가 훨씬 좋습니다.
@dataclass
class Config:
host: str
port: int즉 dataclass는 class의 대체재가 아니라, 특정 형태의 클래스를 빠르게 쓰는 도구입니다.
기본값 처리
가변 기본값에는 default_factory
리스트나 dict 같은 가변 객체를 기본값으로 직접 두면 여러 인스턴스가 같은 객체를 공유하는 문제가 생길 수 있습니다.
field(default_factory=...)가 이 문제를 막아 줍니다.
from dataclasses import dataclass, field
@dataclass
class Team:
members: list[str] = field(default_factory=list)이 규칙은 dataclass에서 가장 자주 실수하는 지점 중 하나입니다. Python은 dataclass에서 이런 가변 기본값 실수를 막기 위해 직접 기본값을 두는 패턴을 거부하고 default_factory 쪽을 유도합니다.
구조 비교
값 객체, 설정 객체, DTO 같은 역할에 특히 잘 맞는다
복잡한 행동보다 "이 필드 묶음을 안전하게 들고 다닌다"가 핵심인 객체에서 dataclass는 특히 빛납니다. 설정, 입력 파라미터, 응답 구조, 좌표 같은 카드가 대표적입니다.
주의할 점
가변 기본값을 직접 두면 인스턴스 간 상태 공유 버그가 생깁니다. dataclass에서는 default_factory를 쓰는 편이 안전합니다.
# ❌ 공유되는 기본 리스트
from dataclasses import dataclass
@dataclass
class Team:
members: list[str] = []
# ✅ 인스턴스마다 새 리스트 생성
from dataclasses import dataclass, field
@dataclass
class Team:
members: list[str] = field(default_factory=list)참고 링크
2 sources