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 코드는 아래 링크에서 자세하게 확인 가능합니다.
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로 선언해주면, 자동으로 초기화 해주는 것으로 착각하여 발생한 에러였네요^^.