코드로 우주평화

Python _ dict의 keys()처럼 dataclass에서 속성 목록 가져오기 본문

나는 이렇게 학습한다/Language

Python _ dict의 keys()처럼 dataclass에서 속성 목록 가져오기

daco2020 2022. 6. 21. 19:09

파이썬에서 객체를 만드는 방법 중에 dataclass가 있다.

@dataclass 데코레이터를 사용하면 타입 유형을 명시한 객체를 만들 수 있다.

 

dataclass를 만드는 코드는 아래와 같다.

from dataclasses import dataclass

@dataclass(frozen=True)
class Dataclass:
    a:int
    b:int
    c:int

data = Dataclass(a=1,b=3,c=5)
print(data) # 출력 : Dataclass(a=1, b=3, c=5)

print(data.a) # 1
print(data.b) # 3
print(data.c) # 5

 

이렇게 만든 객체는 타입 유형을 명시하고 싶을 때나 DTO, 값 객체 등의 불변 객체로도 사용할 수 있다.

 

 

 

 

dataclass에서 속성은 어떻게 확인하나?

먼저 비교를 위해 딕셔너리는 어떻게 가져오는지 먼저 살펴보자.

(#은 출력 값을 의미한다)

 

dict = {"a":2,"b":4,"c":6}

print(dict["a"]) # 2
print(dict["b"]) # 4
print(dict["c"]) # 6

print(dict.keys()) # dict_keys(['a', 'b', 'c'])

 

결과를 보니, dict_keys(['a', 'b', 'c']) 처럼 딕셔너리의 key 들만 배열로 출력된 것을 볼 수 있다. 딕셔너리의 key는 곧 이 글에서 말하는 dataclass 객체의 속성(attribute)이라고 보면 된다.

 

 

 

dataclass도 딕셔너리 keys() 메서드를 사용하면 속성을 가져올 수 있을까?

print(data.keys()) # 'Dataclass' object has no attribute 'keys'

 

어림도 없다... dataclass에는 keys라는 속성(메서드)이 없다고 한다.

 

 

 

dataclass는 딕셔너리와 다르므로 다른 방법을 사용해야한다.

 

'fields'를 추가로 import 하고 아까 만든 data(dataclass로 선언한)를 감싸 출력해보자.

from dataclasses import dataclass, fields

...

print(fields(data))
# 출력 : (Field(name='a',type=<class 'int'>,default=<dataclasses._MISSING_TYPE object at 0x104a83850>,default_factory=<dataclasses._MISSING_TYPE object at 0x104a83850>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD),
Field(name='b',type=<class 'int'>,default=<dataclasses._MISSING_TYPE object at 0x104a83850>,default_factory=<dataclasses._MISSING_TYPE object at 0x104a83850>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD), Field(name='c',type=<class 'int'>,default=<dataclasses._MISSING_TYPE object at 0x104a83850>,default_factory=<dataclasses._MISSING_TYPE object at 0x104a83850>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD))

 

알아보기 쉽게 정렬해보았다.

 

 

결과물을 보니 튜플 형태로 출력된 Field들이 보인다.

 

자세히 보면 각 Field 안에 'name'으로 속성 이름이 명시되어있다. (참고로 개별 Field는 <class 'dataclasses.Field'>라는 객체 형태를 띠고 있다)

 

 

우리의 목적은 data(dataclass로 선언한)의 속성 목록이므로 각 Field의 'name'을 배열에 담으면 된다!

 

 

 

 

Field - name을 리스트 컴프리핸션으로 가져오자.

print([field.name for field in fields(data)])
# 출력 : ['a', 'b', 'c']

 

리스트 컴프리핸션을 통해 field객체의 name을 가져와, data의 속성 이름들을 배열로 만들었다.

 

쉽게 말해 딕셔너리의 keys() 메서드를 사용한 것과 동일한 결과 값을 가져온 것이다!

 

 

 

마무리

최근 dataclass를 많이 사용하게 되면서 이것저것 활용할 곳들이 많아졌다. 그러던 중에 dataclass에 대해 새롭게 배운 것을 글로 정리해보았다. 이 밖에도 여러 가지 기능들과 메서드를 알아두면 유용하게 사용할 수 있을 것이다. 레퍼런스로 공식문서 링크를 남겨둔다.

 

 

 

dataclasses — 데이터 클래스 — Python 3.10.5 문서

이 모듈은 __init__() 나 __repr__() 과 같은 생성된 특수 메서드 를 사용자 정의 클래스에 자동으로 추가하는 데코레이터와 함수를 제공합니다. 원래 PEP 557 에 설명되어 있습니다. The member variables to us

docs.python.org