해당 글은 유튜버 ArajanCodes의 영상을 정리한 글임을 밝힙니다.
파이썬 dataclasses 모듈은 Data-oriented classes (이하 데이터-지향 클래스) 를 만드는데 도움을 준다.
데이터-지향 클래스는 특정 데이터구조를 나타내기 위한 클래스이며 좌표나 벡터값을 나타내기 위한 클래스를 생각하면 이해하기 쉽다.
데이터-지향 클래스와 반대되는 개념으로는 Behavior-oriented class (행동-지향 클래스?) 가 있는데, 이런 클래스의 예시로 몇 가지의 메소드들로 구성되어있는 결제 서비스로 이루어진 클래스를 들 수 있다.
그럼 파이썬 dataclass 모듈은 이런 데이터-지향 클래스를 만드는데 어떤 도움을 준다는 걸까?
데이터 클래스는
그럼 바로 dataclasses 모듈을 사용해서 확인해보자.
import random
import string
def generate_id() -> str:
return "".join(random.choices(string.ascii_uppercase, k=12))
class Person:
def __init__(self, name: str, address: str):
self.name = name
self.address = address
def main() -> None:
person = Person(name="John", address="123 Main st")
print(person)
if __name__=="__main__":
main()
예시에 대한 설명이다.
generate_id()
함수는 12개의 대문자로 된 랜덤 아이디를 생성한다.Person
클래스를 정의하였다.main
함수에서는 123 Main st
에 살고 있는 John
을 실제로 생성하고 출력한다.그럼 이제 첫 예제를 실행시켜 실제로 어떤 것이 출력되는지 보자.
실행 결과를 보면
<__main__.Person object at 0x101100710>
이라는 알 수 없는 값을 출력하는 것을 볼 수 있다.
사실 이 값은 main
함수에서 실제로 생성한 인스턴스의 메모리 주소다. 하지만 우리가 원하는 건 실제로 Person
이 담고 있는 정보 (해당 예시에서는 이름과 주소) 를 출력하는 것이므로, dataclasses 모듈을 사용하기 전에 던더 메소드를 사용해서 이를 구현해보자.
기존 예시에서 Person
클래스 내부에 __str__
메소드를 통해 인스턴스가 출력되었을 때 실제로 어떤 일이 일어나야 하는지 정의할 수 있다.
다음과 같이 구현하여 다시 출력해보자.
...
class Person:
def __init__(self, name: str, address: str):
self.name = name
self.address = address
def __str__(self) -> str:
return f"{self.name}, {self.address}"
...
원했던 정보인 이름과 주소가 예쁘게 출력되는 것을 볼 수 있다. 마찬가지로 그럼 그냥 던더 메소드를 사용하면 되냐?
Person 객체들을 비교해야 할 일이 있거나 (예를 들면 정렬을 해야한다거나)
이름과 주소같은 정보 외에도 성별, 우편번호, 연락처와 같은 정보를 추가해야할 경우에는
다음과 같은 작업들이 필요하다.
별거 아니게 느껴질 수 있지만 변수 하나가 늘어날 때마다 이와 같은 작업을 하는 것은 여간 수고스러운게 아니다.
이런 데이터-지향 클래스의 경우에는 dataclasses
모듈을 사용하면 더 쉽고 빠르게 구현할 수 있다.
먼저 데이터 클래스를 사용하기 전에 dataclasses
모듈을 임포트 해야 한다.
import random
import string
from dataclasses import dataclass
다음으로는 Person
클래스 위에 데코레이터 @dataclass
를 사용해서 해당 클래스가 데이터 클래스임을 명시하자.
그리고 기존에 사용했던 생성자 (__init__
) 과 인스턴스 변수를 출력하기 위해 사용했던 (__str__
) 메소드도 제거해버리자. 두 메소드 모두 데이터 클래스 모듈이 자동으로 생성해줄 것이다.
정확하게는 __str__
메소드가 아닌 __repr__
메소드를 생성한다.
Person
클래스 내부의 인스턴스 변수는 다음과 같이 선언하면 된다.
@dataclass
class Person:
name: str
address: str
Person
클래스의 구현을 굉장히 단순화하였음에도 불구하고 인스턴스가 제대로 생성되었으며, 출력 결과를 보더라도 기존에 구현했던 기능을 모두 지원하고 있음을 알 수 있다.
데이터 클래스를 사용할 때의 주의점은, @dataclass
데코레이터를 빠트렸을 때는 인스턴스 변수가 아닌 클래스 변수만 잔뜩 만들어진다는 것이다.
22분 분량의 영상을 만만하게 생각하고 글을 적기 시작했는데 생각보다 길어져서 다음 편에 이어서..
지금까지 데이터 클래스를 사용해야 하는 이유에 대해서 알아보고 실제로 코드가 간소화되었음을 확인했다. 다음 글에서는 파이썬 데이터 클래스에서 제공하는 편의기능들에 대해서 알아보도록 하겠다.
좋은 글 감사합니다. 자주 올게요 :)