본문 바로가기
프로그래밍 언어(Programming Languages)/파이썬(Python)

[Python] @dataclass로 파이썬 클래스 마스터하기

by 데이터 벌집 2023. 10. 11.
반응형

오늘의 주제는 Python 3.7에서 소개된 '데이터 클래스'에 대한 것입니다. 이 데이터 클래스는 사용자 정의 클래스를 효율적으로 만들어주는  기능이며, 여러분들이 코딩하는 데 도움이 될 것입니다. 이 글을 통해 데이터 클래스가 무엇인지, 언제 쓰는 것이 좋은지 알아보도록 하겠습니다.

데이터 클래스로 파이썬 클래스 마스터하기


데이터 클래스란 무엇인가?

데이터 클래스는 Python 3.7부터 도입된 기능으로, 클래스를 더 간결하고 가독성 있게 정의할 수 있도록 도와주는 기능이다. dataclass 데코레이터를 사용하여 클래스를 정의할 때 필요한 특수 메소드를 자동으로 추가해주어, 클래스를 효율적으로 관리할 수 있다.

 

기본 특징:

  • 자동 초기화 메소드 생성: 데이터 클래스는 __init__ 메소드를 자동으로 생성해준다. 따라서 객체를 초기화할 때 각 필드에 값을 할당하는 코드를 작성하지 않아도 된다.
  • 객체의 문자열 표현: __repr__ 메소드가 자동으로 생성되어, 객체를 출력하면 객체의 필드와 그 값을 알기 쉽게 표시한다.
  • 객체 비교: __eq__ 메소드를 자동으로 생성하여, 같은 필드와 값을 가진 객체는 같다고 판단한다.

주요 특징

 

1. __init__ 메소드 불필요:

 

데이터 클래스(Data Class) 사용:

from dataclasses import dataclass

@dataclass
class Book:
    title: str
    author: str
    pages: int
    genre: str

book = Book("1984", "George Orwell", 328, "Dystopian")
print(book)  # Output: Book(title='1984', author='George Orwell', pages=328, genre='Dystopian')

 

사용자 정의 클래스(User Defined Class) 사용:

class Book_UserDefined:
    def __init__(self, title, author, pages, genre):
        self.title = title
        self.author = author
        self.pages = pages
        self.genre = genre

book_ud = Book_UserDefined("1984", "George Orwell", 328, "Dystopian")
print(book_ud)  # 출력 결과 없음 (출력을 위해 __repr__이 필요)

 

2. 불변성 (Immutability)

 

데이터 클래스(Data Class) 사용:

@dataclass(frozen=True)
class Book:
    title: str
    author: str
    pages: int
    genre: str

book = Book("1984", "George Orwell", 328, "Dystopian")
# book.title = "Animal Farm"  # FrozenInstanceError

 

사용자 정의 클래스(User Defined Class) 사용:

__slots__을 사용하여 불변성을 어느 정도 달성할 수 있습니다. 하지만 완벽한 불변성을 지원하지 않습니다.

class Book_UserDefined:
    __slots__ = ('title', 'author', 'pages', 'genre')
    # ... (다른 메소드 및 __init__)
    
    def __setattr__(self, name, value):
        raise AttributeError("이 클래스는 불변입니다.")

book_ud = Book_UserDefined("1984", "George Orwell", 328, "Dystopian")
# book_ud.title = "Animal Farm"  # AttributeError: 이 클래스는 불변입니다.

 

이와 같이, 데이터 클래스를 사용하면 코드를 훨씬 간결하고 명료하게 만들 수 있습니다.

 

3. 특수 메소드 자동 생성

 

데이터 클래스(Data Class) 사용:

데이터 클래스는 __repr__ 및 __eq__ 메소드를 자동으로 구현합니다.

book1 = Book("1984", "George Orwell", 328, "Dystopian")
book2 = Book("1984", "George Orwell", 328, "Dystopian")
print(book1 == book2)  # Output: True (자동으로 __eq__ 구현)

 

사용자 정의 클래스(User Defined Class) 사용:

__eq__ 메소드를 직접 구현해야 합니다.

class Book_UserDefined:
    # ... (다른 메소드)
    def __eq__(self, other):
        return self.title == other.title and self.author == other.author and self.pages == other.pages and self.genre == other.genre

book1_ud = Book_UserDefined("1984", "George Orwell", 328, "Dystopian")
book2_ud = Book_UserDefined("1984", "George Orwell", 328, "Dystopian")
print(book1_ud == book2_ud)  # Output: True (직접 __eq__ 구현)

 

4. Field 옵션 설정 가능:

 

데이터 클래스 필드에 대해 추가 설정을 할 수 있습니다. 각 필드에 대한 기본값(default), 기본 팩토리 함수(default_factory) 등을 설정할 수 있습니다.

데이터 클래스(Data Class) 사용:

데이터 클래스는 __repr__ 및 __eq__ 메소드를 자동으로 구현합니다.

from dataclasses import dataclass, field

@dataclass
class Book:
    title: str
    author: str
    pages: int = field(default=0, repr=False)

 

위 예제에서 pages 필드는 기본값을 0으로 가지며, __repr__ 메소드에 포함되지 않습니다.

 

5. post_init 메소드 활용:

 

데이터 클래스는 __post_init__ 메소드를 제공하여 객체 초기화 후 추가적인 설정이나 계산을 수행할 수 있습니다.

데이터 클래스(Data Class) 사용:

from dataclasses import dataclass

@dataclass
class Book:
    title: str
    author: str
    pages: int
    
    def __post_init__(self):
        self.is_long = True if self.pages > 300 else False

__post_init__ 메소드에서는 pages 속성을 기반으로 is_long 속성을 동적으로 설정합니다.

 

5. asdict() 함수

 

dataclasses.asdict() 함수를 사용하면 데이터 클래스의 인스턴스를 딕셔너리로 변환할 수 있습니다:

데이터 클래스(Data Class) 사용:

from dataclasses import asdict

book_dict = asdict(book1)
print(book_dict)  # 출력: {'title': '1984', 'author': 'George Orwell', 'pages': 328}

 

 


데이터 클래스의 적절한 사용 시기

 

  • 사용 권장 시기:
    • 주로 데이터를 담는 클래스를 정의할 때: 데이터 클래스는 필드의 집합을 가진 클래스를 간단하게 정의하는데 적합합니다.
    • 간단한 메소드를 가진 클래스를 정의할 때: 데이터 클래스를 활용하면, 간단한 메소드를 쉽게 추가할 수 있습니다.
  • 사용을 피해야 할 시기:
    • 다중 상속이나 복잡한 상속 구조를 가진 클래스를 만들 때: 데이터 클래스는 다중 상속이나 복잡한 상속 구조를 가진 클래스에서는 사용을 피하는 것이 좋습니다.
    • 퍼포먼스에 민감한 경우: 위에서 언급한 런타임 오버헤드 때문에, 퍼포먼스에 매우 민감한 상황에서는 사용을 피해야 할 수 있습니다.

데이터 클래스는 특히 데이터를 담는 객체를 쉽고 빠르게 정의할 때 유용합니다. 그러나 모든 상황에 적합한 것은 아니며, 특정 상황에서는 일반 클래스를 사용하는 것이 더 나을 수 있습니다. 개발 시 상황과 요구 사항을 고려하여 데이터 클래스의 사용 여부를 결정하시길 바랍니다.

반응형