본문 바로가기
프로그래밍

고급 파이썬: 데이터클래스

by it-view 2022. 3. 10.
반응형

Python 3.7에 도입된 Python Dataclasses를 살펴보겠습니다.

데이터클래스는 파이썬 개발자로서 당신의 삶을 훨씬 쉽게 만들어 줄 파이썬 모듈에 새롭게 추가된 것이다. 고급 주제는 아니지만 이번 시리즈에서 다루도록 하겠습니다. 이 모듈은 init(), _repr() 등 생성된 특수 메소드를 사용자 정의 클래스에 자동으로 추가하는 데코레이터 및 기능을 제공합니다. 그것은 원래 PEP 557에 기술되었다.

지금까지 이 시리즈에서

  • Python 클래스, 객체 및 MRO
  • 데이터클래스(현재 게시물)
 

왜 그리고 어떻게?

새로운 기능을 추가하려면 기존 시스템에 더 많은 기능이 필요하거나 (교체 시) 기대에 미치지 못하는 기능이 있어야 합니다. 따라서 우리는 왜 python.org이 데이터클래스를 도입했는지 알아야 한다.

데이터클래스 사용 안 함:

우리가 트위터와 같은 새로운 응용 프로그램을 만들고 있고 이 응용 프로그램에는 트윗 세부 정보를 추적하기 위한 "트위츠"라는 클래스가 있다고 가정합니다. 이렇게 빠르고 거의 생산 준비가 완료된 클래스가 무엇인지 살펴보겠습니다.

오, 잠깐만! 이제 제품 관리자가 트윗 게시물에 설명을 추가하는 기능을 추가하기를 원하므로 새 클래스 변수를 도입해야 합니다.!!

 

이제 너는 거의 모든 수업을 다시 써야 해. 또 2시간 낭비했다.

데이터클래스 사용:

자, 이제 @dataclass로 해보자.


from dataclasses import dataclass, field
from datetime import datetime
from uuid import UUID, uuid4
@dataclass(frozen=True, order=True)
class Tweets:
    """ Class to store tweets of users """

    tweet_body: str = None
    tweet_time: datetime = datetime.utcnow()
    tweet_id: UUID = uuid4()
    tweet_lang: str = 'en-IN'
    tweet_place: str = 'IN'
    tweet_retweet_count: int = 0
    tweet_hashtags: list[str] = field(default_factory=list)
    tweet_user_id: str = None
    tweet_user_name: str = None

바로 그겁니다. 끝났어요. 모든 상용어 코드는 파이썬이 직접 처리했다. 그리고 새로운 클래스 변수 추가에 대해서는 위와 같이 선언하고 잊어버리면 됩니다. 이 수업에서 이용할 수 있는 모든 방법을 살펴보겠습니다.

 

>>> inspect.getmembers(Tweets, predicate=inspect.isfunction) 
[('__delattr__', <function Tweets.__delattr__ at 0x0000015EE175A440>), 
 ('__eq__', <function Tweets.__eq__ at 0x0000015EE1759EA0>), ('__ge__', <function Tweets.__ge__ at 0x0000015EE175A320>), ('__gt__', <function Tweets.__gt__ at 0x0000015EE175A200>), ('__hash__', <function Tweets.__hash__ at 0x0000015EE175A4D0>), ('__init__', <function Tweets.__init__ at 0x0000015EE1759C60>), ('__le__', <function Tweets.__le__ at 0x0000015EE175A0E0>), ('__lt__', <function Tweets.__lt__ at 0x0000015EE1759FC0>), ('__repr__', <function Tweets.__repr__ at 0x0000015EE1759BD0>), ('__setattr__', <function Tweets.__setattr__ at0x0000015EE175A3B0>)]

python이 setattr_() 및 _delattr()을 이미 만들어 불변성을 만든 것 같습니다. Python은 frozen=True 를 추가했으며 오더=를 추가할 때 __le(), lt(), gt_(), ge()를 추가했기 때문에 이 작업을 수행했습니다.맞습니다(코드가 이미 상당히 길었기 때문에 이전 스타일 클래스 선언에서는 이 4가지를 구현하지 않았습니다).

기본값은 기본값이 없는 값 다음에 기본값이 있는 값을 선언해야 합니다. 변경 가능한 개체(여기에 목록 개체)의 기본값인 경우 default_factory를 사용해야 합니다. 데이터 클래스에서 가져올 수 있는 필드()를 사용하여 선언할 수 있습니다. 해당 클래스의 모든 인스턴스가 동일한 목록을 사용하는 것을 원하지 않기 때문에 이것은 매우 중요합니다.

클래스에 eq_(), __init() 또는 hash()을(를) 두지 마십시오.


@dataclass(init=False, repr=False, eq=Flase, unsafe_hash=False)
class Tweets():
 

우리는 _repr() 및 _eq() 방법에서 반환되어야 하는 것에 대한 통제력도 가지고 있습니다.


tweet_retweet_count: int = field(repr=False, compare=False,                    
                                                                  default=0)

repr=False를 만들 때 이 필드는 생성된 _repr() 메서드에 의해 반환되는 문자열에 포함되지 않으며 compare=False의 경우 생성된 동등 및 비교 메서드(eq()), gt() , _lt( ) 등에서 tweat_count를 제외합니다.

post init 처리를 위해 _post_init()가 있습니다.


@dataclass
class ResponseOnTweet:

    tweet_total_response_count: int = field(init=False)
    tweet_retweet_count: int = 0
    tweet_comment_count: int = 0 
    tweet_like_count: int = 0
    def __post_init__(self):
            self.tweet_total_response_count = self.tweet_retweet_count  
                 + self.tweet_comment_count + self.tweet_like_count
 

결론

재밌지 않아요? 음, 확실히 데이터클래스를 즐겨 써요. 저는 여러분들도 정말 구체적이고 관습적인 것을 원하지 않는 한 결코 옛날 방식으로 돌아가지 않을 것이라고 생각합니다. 이것으로 이 글을 끝내고 다음 글에서는 언제나처럼 트위터나 링크드인을 통해 제게 연락해주실 제안이나 생각이 있으시면 파이썬의 데코레이터에 대해 알아보겠습니다. 이따가 봐요.

댓글