Python

python dataclass

Prower 2022. 7. 21. 00:40
728x90
반응형
  • python 3.7 부터 추가된 모듈
  • python에서 class를 통해 데이터를 저장하면 type 안전하게 데이터를 저장할 수 있음
  • data를 class로 저장하거나 비교, 출력하는 기능을 편하게 해주는 모듈

dataclass를 사용하지 않은 경우

데이터 저장

class Foo:
    def __init__(self, id: int, name: str, admin: bool):
        self.id = id
        self.name = name
        self.admin = admin
  • 각 데이터를 저장하는데만 변수가 3번이 사용되어 데이터를 저장하기 위해서 너무 많은 코드가 필요하다
  • 변수 갯수가 많아지면 더욱 많은 작업이 필요하며, 휴먼에러가 발생하기도 쉽다.

동등 비교

  • 일반적인 class에서 동등 비교를 위해선 __eq__()를 상속받아 구현을 해줘야 함
class Foo:
    def __init__(self, id: int, name: str, admin: bool):
        self.id = id
        self.name = name
        self.admin = admin
​
    def __eq__(self, other):
        if self.__class__ == other.__class__:
            return (self.id, self.name, self.admin) == (other.id, other.name, other.admin)
        return False

출력

  • 혹은 내부 리소스를 출력하기 위해선 __repr__() 를 상속받아 각 필드를 출력해주도록 해야 함
class Foo:
    def __init__(self, id: int, name: str, admin: bool):
        self.id = id
        self.name = name
        self.admin = admin
​
    def __repr__(self):
        return f"id={self.id}, name={self.name}, admin={self.admin}"

dataclass를 사용하는 경우

  • 위 경우와 같이 일반적인 클래스로는 데이터를 저장하는 것 뿐만 아니라 기타 편의기능을 직접 구현해야 하는 불편함이 있음
  • dataclass를 사용하여 이러한 불편함을 해소하고 생산성을 증가시킬 수 있음

데이터 저장

from dataclasses import dataclass
​
@dataclass
class Foo:
    id: int
    name: str
    admin: bool
  • @dataclass 어노테이션을 추가하는 것 만으로 구현 가능
  • 데이터 클래스로 지정되면 __init__, __repr__, __eq__ 같은 기능이 자동으로 구현됨
from dataclasses import dataclass
​
@dataclass
class Foo:
    id: int
    name: str
    admin: bool
​
foo1 = Foo(1, "foo", True)
foo2 = Foo(1, "foo", True)
print(foo1)
print(foo1 == foo2)

출력 결과

Foo(id=1, name='foo', admin=True)
True

불변 데이터 클래스

  • 해당 데이터 클래스의 데이터의 불변성이 보장되어야 한다면 frozen 옵션을 사용하여 설정 가능
@dataclass(frozen=True)
class Foo:
    id: int
    name: str
    admin: bool

set와 dictionary에서 사용

  • 데이터 클래스의 인스턴스는 기본적으로 hashable 하지 않기 때문에 set나 dictionary의 키값으로 사용할 수 없음
  • 데이터 클래스를 hashable하게 사용하고 싶다면 unsafe_hash 옵션을 사용하여 설정 가능
@dataclass(unsafe_hash=True)
class Foo:
    id: int
    name: str
    admin: bool
​
foo1 = Foo(1, "foo", True)
foo2 = Foo(1, "foo", True)
​
foo_set = set([foo1, foo2])
​
print(foo_set)

출력 결과

{Foo(id=1, name='foo', admin=True)}
  • 위 경우처럼 set의 값으로 할당하여 중복 제거가 가능해짐

기본값 설정

  • 데이터 클래스에서 기본값을 가진 필드는 순서상 기본값을 갖지 않은 필드의 뒤에 선언되되어야 한다
@dataclass()
class Foo:
    id: int
    name: str = "foo"
    admin: bool = True
    friends: List = []
  • 일반적인 값은 기본값으로 설정할 수 있지만 list의 경우 일반적인 값으로 기본값 설정 불가능
from dataclasses import dataclass, field
from typing import List
​
@dataclass()
class Foo:
    id: int
    name: str
    admin: List = field(default_factory=list)
  • 위 경우처럼 field 의 내부 설정으로 default_factory 에 type을 전달하여 설정

ref

728x90
반응형