Python 강좌 / dataclass로 데이터 중심 클래스 만들기
dataclass는 필드 선언을 바탕으로 초기화·표현·동등 비교 같은 메서드를 생성하는 표준 라이브러리 기능입니다. 데이터 기록을 간결하게 표현하지만 타입 검사나 업무 검증까지 자동으로 수행하지는 않습니다.
데이터 중심 클래스의 반복 줄이기
dataclass는 클래스의 타입 어노테이션에서 필드를 찾습니다. 기본적으로 __init__·__repr__·__eq__ 같은 메서드를 생성하므로 짧은 기록용 클래스를 작성하기 편리합니다. 모든 클래스에 적용해야 하는 것은 아니며 복잡한 동작 중심 객체와 목적이 다릅니다.
관련 동작과 지원 조건은 dataclass로 데이터 중심 클래스 만들기 관련 공식 문서에서 확인할 수 있습니다.
변경 가능한 기본값은 field(default_factory=list)처럼 생성 함수를 지정합니다. 모든 인스턴스에 같은 리스트를 공유하도록 만들지 않기 위한 장치입니다.
전체 예제와 실행 결과
별도의 실습 폴더에서 아래 파일을 UTF-8로 저장합니다. 가상환경을 선택한 터미널에서 python data_records.py 명령으로 실행합니다. macOS·Ubuntu에서 가상환경을 사용하지 않는 경우 명령 이름을 python3으로 바꿉니다.
data_records.py 파일의 전체 내용입니다.
from dataclasses import dataclass, field
@dataclass
class Expense:
name: str
amount: int
tags: list[str] = field(default_factory=list)
def __post_init__(self):
if type(self.amount) is not int or self.amount < 0:
raise ValueError("invalid amount")
a = Expense("lunch", 8000)
b = Expense("bus", 2500)
a.tags.append("work")
print(a)
print(b.tags)
print(a == Expense("lunch", 8000, ["work"]))
예상 결과는 다음과 같습니다.
Expense(name='lunch', amount=8000, tags=['work']) [] True
검증과 frozen의 한계
__post_init__은 생성된 __init__ 이후 호출되는 후처리 지점입니다. 예제는 생성 시 금액을 검증하지만 이후 a.amount = -1 대입까지 막지는 않습니다. 지속적인 상태 검증이 필요하면 property나 불변 설계 등을 별도로 검토합니다.
frozen=True는 일반적인 필드 재대입을 제한하지만 내부 리스트의 append까지 막는 깊은 불변성은 아닙니다. 불변 기록을 원한다면 내부 필드도 튜플 등 적절한 자료형으로 구성하고 실제 사용 계약을 확인해야 합니다.
직렬화와 비교 범위 확인하기
필드가 같으면 동등 비교가 참이 될 수 있지만 그 규칙이 업무상의 동일성을 대신하는 것은 아닙니다. 같은 금액과 이름을 가진 지출 두 건이 같은 거래라고 단정하면 안 됩니다. 실제 식별자는 별도로 설계합니다.
dataclasses.asdict는 딕셔너리 변환을 도와주지만 날짜·Decimal을 JSON으로 저장하는 문제까지 자동 해결하지 않습니다. tags가 서로 독립인지, 잘못된 금액 생성이 거부되는지 각각 확인하고 변환·저장 규칙은 별도로 테스트합니다.




