본문 바로가기

개발

파이썬 3.7부터 도입된 dataclasses에 대해 알아보자

반응형
from dataclasses import dataclass, field

...(생략)

@dataclass
class Client:
    interface: websockets.server.WebSocketServerProtocol = field(repr=False)
    sid: str = field(default_factory=partial(generate_code, 36))

    ...(생략)
  • 찾아보니 파이썬 3.7부터 표준 라이브러리로 등재되었다고 한다. 파이썬 3.6에서 사용하기 위해선 pip install dataclasses를 통해 사용할 수 있다. (파이썬 3.6 지원불가)
  • 이는 데이터 클래스를 보다 용이하게 선언해주는 데코레이터이다. 파이썬 3.6부터 추가된 기능이며 Type Annotation을 지원한다.
  • 클래스에 @dataclass 데코레이터를 사용하면 __int__, __repr__, __eq__ 등의 메소드를 자동으로 정의해 준다.
from dataclasses import dataclass

# 이렇게 @dataclass 데코레이터를 클래스 위에 붙여준다.
@dataclass
class Item:
    id: int
    name: str


print(Item(1, "Apple"))
print(Item(2, "Banana"))

실행결과

>> 
Item(id=1, name='Apple')
Item(id=2, name='Banana')
  • 위의 코드 같은 경우 데코레이터를 사용하지 않는다면 __init__메소드에 id와 name을 변수로 받는 것이 없기 때문에 에러가 발생한다. 만약 __init__메소드를 정의했다하더라도, __repr__메소드가 정의되어 있지 않기 때문에 아래와 같이 출력된다.
class Item:
    id: int
    name: str

    def __init__(self, id: int, name: str):
        self.id = id
        self.name = name


print(Item(1, "Apple"))
print(Item(2, "Banana"))

실행결과

>>
<__main__.Item object at 0x7fd501796898>
<__main__.Item object at 0x7fd501796898>
  • 데이터를 정의하는 클래스라는 점에서 기존 파이썬의 collections.namedtuple 비슷하다. 하지만,@dataclass를 사용한 클래스는 말 그대로 클래스라는 점에서 메소드나 프로퍼티를 추가할 수 있다.

  • dataclasses.field를 사용하면 해당 프로퍼티에 대한 설정을 해줄 수 있다. (ex: default_factory, repr여부)

from dataclasses import dataclass, field
from functools import partial
import uuid


@dataclass
class Factory:
    id = field(default_factory=partial(uuid.uuid4))
    items = field(default_factory=list)


f1 = Factory()
print(f1.items)
f1.items += ['apple', 'banana']
print(f1.items)
print(f1)

실행결과

>>
[]
['apple', 'banana']
Factory(id=UUID('990091ef-6058-4754-b1f5-78e3546cc7bd'), items=['apple', 'banana'])
  • 파이썬의 Type Annotation을 활용하긴하지만, 해당 타입이 맞는지 검증(validate)하지는 않는다.
  • 만약 dataclasses를 사용하고 검증까지 원한다면 pydantic의 pydantic.dataclasses를 사용하면 된다. (pydantic 라이브러리는 추후에 제대로 공부해서 정리하겠다.) [참고]

참조


반응형