Python @dataclass 사용시 asdict Error 해결법

devkingsejong·2021년 8월 19일
0

삽질

목록 보기
3/3
post-thumbnail

Error 내용

Traceback (most recent call last):
  in <module> temp = dataclasses.asdict(TempDataClass("1", "2"))
  File "/Versions/3.8/lib/python3.8/dataclasses.py", line 1073, in asdict
    return _asdict_inner(obj, dict_factory)
  File "/Versions/3.8/lib/python3.8/dataclasses.py", line 1080, in _asdict_inner
    value = _asdict_inner(getattr(obj, f.name), dict_factory)
AttributeError: 'TempDataClass' object has no attribute 'temp_value'

Python dataclass는 data를 관리하는 Class를 쉽게 개발하고 관리할 수 있도록 도와주는 클래스로,
@dataclass와 같이 Decorator형태로 선언하여 사용할 수 있습니다.

일반적으로 dataclass는 __init__부를 자동으로 구현해주지만, init=false를 선언해주거나, 개발자가 __init__ 함수를 직접 구현한 경우에는 그렇지 않습니다.

@dataclass
class TestDataClass:

    data1: str
    data2: str
    data3: str = field(default_factory=get_data3_value)


    def __init__(self, data1: str, data2: str):
        self.data1 = data1
        self.data2 = data2

저의 경우 위와 같이

data1과 data2는 사용자로부터 값을 받고, data3은 get_data3_value라는 함수를 통해 자동으로
값을 지정하도록 구현하였는데, data serialize에 실패하는 에러가 발생하였습니다.

이에 대한 해결책은 아래와 같습니다.


1. 클래스 내부의 __init__ 부분 삭제

dataclass는 기본 설정적로 __init__를 생성해 주는 것기 때문에 직접 구현할 필요가 없습니다.
__init__를 직접구현하지 않는 경우, python에서는 (위 코드를 기준으로)

def __init__(self, data1: str, data2: str):
        self.data1 = data1
        self.data2 = data2
        self.data3 = _dflt_data3() if kor_name is _HAS_DEFAULT_FACTORY else data3

와 같은 형태로 구현됩니다.

여기서 _dflt_data3()는 dataclass.globals의 key값 명으로, 해당키에는 아래 사진과 같이 default_factory의 함수와 연결되어 있습니다.

해당 작업을 진행하는 Class 코드는 아래 링크에서 자세하게 확인 가능합니다.

https://github.com/python/cpython/blob/17b16e13bb444001534ed6fccb459084596c8bcf/Lib/dataclasses.py#L450

2. __init__ 구문을 (1)에서 생성한 것과 유사하게 변경

만약 @dataclass(init=true) 옵션을 사용하지 않고, 직접 구현하고 싶다면
당연히 (1) 항목에서 python이 자동으로 만들어 주는 것과 같이 구현해주면 됩니다.

ex)

def __init__(self, data1: str, data2: str):
        self.data1 = data1
        self.data2 = data2
        self.data3 = get_data3_value()

field로 선언해주면, 자동으로 초기화 해주는 것으로 착각하여 발생한 에러였네요^^.

0개의 댓글