dataclass란?

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

클래스를 만들 때 가장 많이 반복되는 코드는 이런 형태다.

필드만 많아져도 코드가 계속 반복된다.

 

이런 데이터 저장용 클래스를 더 간단하게 만들기 위해 나온 것이 dataclass다.

> 클래스의 반복 코드를 자동 생성해주는 기능

from dataclasses import dataclass

@dataclass
class Product:
    name: str
    price: int

위 코드처럼 사용하고

실제로는 내부적으로 아래 코드가 자동 생성된다.

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

즉 @dataclass는

- __init__

- __repr__

- __eq__

같은 메서드를 자동으로 만들어준다.

 

예를 들어

@dataclass
class User:
    name: str
    age: int

u = User("Alice", 20)

print(u)

# 출력
User(name='Alice', age=20)

이 문자열 표현(__repr__)도 자동 생성된 것이다.


__post__init ?

dataclass가 __init__을 자동 생성하기 떄문에 직접 __init__을 수정하기 어렵다.

하지만 객체 생성 직후 추가 작업이 필요할 때

- 값 검증

- 문자열 정리

- 타입 변환

- 계산 필드 생성

등 이럴 때 사용하는 것이 __post_init__이다.

 

> dataclass의 자동 생성된 __init__ 실행 이후 자동 호출되는 메서드

from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int

    def __post_init__(self):
        self.name = self.name.strip()

        if self.age < 0:
            raise ValueError("나이는 음수가 될 수 없습니다")
 
 # 객체 생성
 u = User("  Alice  ", 20)

print(u.name)

# 출력
Alice

 

실행순서는 다음과 같다.

def __init__(self, name, age):
    self.name = name
    self.age = age
    self.__post_init__()

1. 자동 생성된 __init__

2. 필드 저장

3. __post_init__

 

위 코드에 __init__이 없는 이유는

@dataclass가 자동생성해주기 때문에 실제로는 내부에 자동 생성된 __init__이 존재한다.