목차
dataclass란?
Python 3.7에서 도입된 dataclass는 데이터를 저장하기 위한 클래스를 쉽게 생성할 수 있게 해주는 데코레이터이다. 보일러플레이트 코드를 줄이고 데이터 중심의 클래스를 더 효율적으로 작성할 수 있게 해준다.
전통적인 클래스에서는 __init__, __repr__, __eq__ 등의 특수 메서드를 직접 구현해야 했지만, dataclass를 사용하면 이러한 메서드들이 자동으로 생성된다.
1. 기본 사용법
클래스 정의 위에 @dataclass 데코레이터를 추가하고, 각 필드의 타입을 명시하면 완전한 기능을 갖춘 클래스가 생성된다.
from dataclasses import dataclass
@dataclass
class Book:
title: str
author: str
price: float
in_stock: bool = True
# 사용 예시
book = Book("파이썬 완벽 가이드", "홍길동", 25000)
print(book) # Book(title='파이썬 완벽 가이드', author='홍길동', price=25000, in_stock=True)
여기서 dataclass는 자동으로 다음을 생성한다:
- __init__ 메서드: 객체 초기화를 위한 생성자
- __repr__ 메서드: 객체의 문자열 표현을 위한 메서드
- __eq__ 메서드: 객체 간 비교를 위한 메서드
2. 클래스 변수와 인스턴스 변수
dataclass에서는 클래스 변수와 인스턴스 변수의 선언 방식이 일반 클래스와 다르다.
- 인스턴스 변수 - 타입 어노테이션이 없음
- 클래스 변수 - 1. 타입 어노테이션이 없거나 2. ClassVar[타입]이 명시되있음
기본적인 구분 방법
from dataclasses import dataclass
from typing import ClassVar
@dataclass
class Student:
# 인스턴스 변수 (타입 어노테이션 필수)
name: str
age: int
# 클래스 변수 (타입 어노테이션 없음)
school_name = "파이썬 고등학교"
# 타입 힌트가 있는 클래스 변수
MAX_AGE: ClassVar[int] = 20
3. 고급 기능
3.1 필드 옵션 설정
field() 함수를 사용하면 필드의 동작을 더 세밀하게 제어할 수 있다. default_factory를 사용하여 가변 객체의 기본값을 안전하게 설정하거나, init=False로 초기화에서 제외할 수 있다.
from dataclasses import dataclass, field
@dataclass
class Student:
name: str
scores: list[int] = field(default_factory=list)
average: float = field(init=False)
def __post_init__(self):
self.average = sum(self.scores) / len(self.scores) if self.scores else 0
3.2 불변 데이터클래스 만들기
데이터의 불변성이 필요한 경우, frozen 매개변수를 사용하여 인스턴스의 속성을 변경할 수 없게 만들 수 있다. 이는 설정값이나 상수 데이터를 다룰 때 특히 유용하다.
@dataclass(frozen=True)
class Configuration:
host: str
port: int = 8080
config = Configuration("localhost")
# config.port = 9000 # 이 코드는 FrozenInstanceError를 발생시킨다
3.3 상속 활용하기
dataclass도 일반 클래스처럼 상속을 지원한다. 이를 통해 코드 재사용성을 높이고 계층적인 데이터 구조를 만들 수 있다.
@dataclass
class Vehicle:
brand: str
model: str
year: int
@dataclass
class Car(Vehicle):
doors: int = 4
fuel_type: str = "gasoline"
4. Best Practice와 주의사항
4.1 타입 힌트 활용하기
dataclass는 타입 힌트와 함께 사용할 때 가장 효과적이다. IDE의 자동 완성과 타입 검사 기능을 최대한 활용할 수 있다.
from typing import Optional
@dataclass
class User:
username: str
email: str
age: Optional[int] = None
4.2 기본값 설정 시 주의 사항(가변 객체 다루기)
dataclass에서 가변 객체(list, dict, set 등)를 다룰 때는 특별한 주의가 필요하다. 기본값으로 직접 가변 객체를 할당하면 모든 인스턴스가 같은 객체를 공유하게 되어 예기치 않은 버그가 발생할 수 있다. 이를 방지하기 위해 field(default_factory=)를 사용해야 한다.
# 잘못된 예시
@dataclass
class Wrong:
items: list = [] # 모든 인스턴스가 같은 리스트를 공유
# 올바른 예시
@dataclass
class Right:
items: list = field(default_factory=list) # 각 인스턴스가 독립적인 리스트를 가짐
4.3 불변성 고려하기
데이터의 무결성이 중요한 경우 frozen=True 사용을 고려하는 것이 좋다. 실수로 인한 데이터 변경을 방지하고 함수형 프로그래밍 스타일을 지원할 수 있다.
4.4 클래스 변수와 인스턴스 변수 배치
코드의 가독성과 유지보수성을 높이기 위해서는 클래스 내의 변수들을 일관된 순서로 배치해야 한다. 인스턴스 변수를 먼저 선언하고, 그 다음에 클래스 변수를 선언하는 것이 권장된다.
@dataclass
class Example:
# 1. 먼저 인스턴스 변수(필드)를 선언
name: str
value: int
# 2. 그 다음 ClassVar를 사용한 클래스 변수
VERSION: ClassVar[str] = "1.0"
MAX_VALUE: ClassVar[int] = 100
# 3. 마지막으로 일반 클래스 변수
status = "active"
결론
dataclass는 데이터를 다루는 클래스를 작성할 때 매우 유용한 도구이다. 보일러플레이트 코드를 줄이고, 가독성을 높이며, 실수를 줄일 수 있다. 특히 데이터 모델링, API 응답 처리, 설정 관리 등에서 큰 효과를 발휘한다.
'Python > 문법' 카테고리의 다른 글
[Python] Enum 정리 (0) | 2025.04.12 |
---|---|
[Python] 비동기(Asynchronous) 문법 이해하기 (0) | 2025.02.08 |
[Python] Module과 Package (0) | 2025.01.18 |
[Python] import 문 사용 팁 (0) | 2025.01.13 |
[Python] Module import로 이해하는 Namespace와 Scope (1) | 2025.01.09 |