Python @dataclass

Dev Smile·2025년 2월 23일
0

1. Dataclass란?

Python의 dataclass는 데이터 중심의 클래스를 간단하게 정의할 수 있도록 도와주는 기능입니다.
일반적으로 데이터를 저장하는 용도로 클래스를 사용할 때, __init__, __repr__, __eq__ 등의 메서드를
일일이 구현해야 하지만, dataclass를 사용하면 이러한 작업을 자동화할 수 있습니다.

Python 3.7에서 도입되었으며, dataclasses 모듈에서 제공됩니다.

2. Dataclass 사용법

기본 사용법

from dataclasses import dataclass

@dataclass
class Person:
    name: str
    age: int

p1 = Person(name="Alice", age=30)
print(p1)  # Person(name='Alice', age=30)

위 코드에서 dataclass 데코레이터를 사용하여 Person 클래스를 정의하면,
자동으로 __init__, __repr__, __eq__ 등의 메서드가 생성됩니다.

기본값 설정

필드에 기본값을 지정할 수도 있습니다.

@dataclass
class Person:
    name: str
    age: int = 25  # 기본값 설정

p1 = Person(name="Bob")
print(p1)  # Person(name='Bob', age=25)

필드 속성 설정

dataclass에서는 field()를 사용하여 필드의 동작을 보다 정교하게 제어할 수 있습니다.

from dataclasses import dataclass, field

@dataclass
class Person:
    name: str
    age: int = field(default=25, metadata={"info": "나이 정보"})
    friends: list = field(default_factory=list)  # 기본값으로 빈 리스트 지정

p1 = Person(name="Charlie")
p1.friends.append("David")
print(p1)  # Person(name='Charlie', age=25, friends=['David'])

비교 및 해싱 가능 여부 설정

dataclass는 기본적으로 객체를 비교할 수 있도록 __eq__ 메서드를 자동으로 생성합니다.
하지만 특정 설정을 변경할 수도 있습니다.

@dataclass(order=True)
class User:
    id: int
    username: str

u1 = User(1, "Alice")
u2 = User(2, "Bob")
print(u1 < u2)  # True (id를 기준으로 비교)

3. Dataclass의 장단점

장점

  1. 코드 간결성: __init__, __repr__, __eq__ 등의 메서드를 자동 생성하여 코드량이 줄어듭니다.
  2. 유지보수 용이: 데이터 중심 클래스의 정의가 간단해지므로 유지보수가 쉬워집니다.
  3. 기본값 및 필드 속성 제어 가능: field()를 이용하여 다양한 속성을 설정할 수 있습니다.
  4. 비교 및 정렬 기능 지원: order=True를 설정하면 객체 비교가 가능합니다.

단점

  1. 동적 속성 추가 제한: dataclass로 생성된 객체는 기본적으로 slots을 사용하지 않지만, frozen=True를 설정하면 속성을 동적으로 추가할 수 없습니다.
  2. 가변 타입의 기본값 문제: 리스트나 딕셔너리 같은 가변 객체를 기본값으로 설정하면 예상치 못한 동작이 발생할 수 있습니다. default_factory를 사용하는 것이 안전합니다.
  3. 상속 시 제약: 여러 개의 부모 클래스를 상속할 경우 dataclass의 동작이 복잡해질 수 있습니다.
  4. 성능 오버헤드: 작은 규모의 클래스에서는 dataclass가 필요 이상으로 많은 기능을 제공하여 성능 저하를 초래할 수 있습니다.
  5. 객체 직렬화 제한: dataclass 객체는 pickle과 같은 일부 직렬화 라이브러리와 완전히 호환되지 않을 수 있습니다.

4. Dataclass 활용 예제

JSON 변환

dataclass를 사용하면 객체를 JSON으로 쉽게 변환할 수 있습니다.

import json
from dataclasses import dataclass, asdict

@dataclass
class Product:
    id: int
    name: str
    price: float

p1 = Product(1, "Laptop", 999.99)
p1_json = json.dumps(asdict(p1))  # JSON 변환
print(p1_json)  # {"id": 1, "name": "Laptop", "price": 999.99}

데이터 검증과 활용

dataclass를 사용하여 입력 데이터를 검증하는 것도 가능합니다.

@dataclass
class Temperature:
    celsius: float
    
    @property
    def fahrenheit(self) -> float:
        return self.celsius * 9 / 5 + 32

t = Temperature(25)
print(t.fahrenheit)  # 77.0

상속을 활용한 확장

Dataclass는 상속을 통해 확장할 수 있습니다.

@dataclass
class Employee:
    name: str
    department: str

@dataclass
class Manager(Employee):
    team_size: int

m1 = Manager(name="Eve", department="IT", team_size=10)
print(m1)  # Manager(name='Eve', department='IT', team_size=10)

데이터 클래스의 불변성 유지

frozen=True 옵션을 사용하면 객체가 불변(immutable)하게 설정됩니다.

@dataclass(frozen=True)
class Config:
    setting: str

c = Config(setting="dark mode")
# c.setting = "light mode"  # AttributeError 발생

자동 ID 생성

객체마다 자동으로 고유한 ID를 부여할 수도 있습니다.

import uuid
from dataclasses import dataclass, field

@dataclass
class Task:
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    description: str

new_task = Task(description="Complete project")
print(new_task)  # Task(id='...', description='Complete project')

0개의 댓글

관련 채용 정보