반응형
파이썬 3.7부터 보다 간편하게 클래스를 생성할 수 있는 dataclass
가 추가됐다. dataclass
를 사용하여 Getter/Setter를 추가할 때 발생한 문제점과 해결 방법에 대해 기술한다.
파이썬에서 Getter/Setter를 사용하려면 @proprety와 @요소.setter라는 특수한 데코레이터를 사용해야한다. 먼저 일반적인 클래스의 경우 어떻게 사용하는지부터 살펴본다.
class User:
def __init__(self, id: str, pw: str):
self.id = id
self._pw = pw
@property
def pw(self):
return self._pw
@pw.setter
def pw(self, value: str):
self._pw = value
if __name__ == '__main__':
user = User(id='hide', pw='hide123')
print(user.__dict__)
Output: {'id': 'hide', '_pw': 'hide123'}
위처럼 정의해주면 실제 내부적으로는 _pw
라는 변수를 사용했지만 클래스를 생성할 때 pw
라는 변수를 통해 값을 할당해줄 수 있다. 만약 위의 방식이 아닌 새롭게 추가된 dataclass를 통해 클래스를 생성해도 동일하게 동작할까?
from dataclasses import dataclass
@dataclass
class User:
id: str
_pw:str
@property
def pw(self):
return self._pw
@pw.setter
def pw(self, value: str):
self._pw = value
if __name__ == '__main__':
user = User(id='hide', pw='hide123')
print(user.__dict__)
Output: NameError: name 'pw' is not defined
코드의 결과에도 명시해놨지만 pw
가 정의되지 않았다는 오류가 발생한다. 위 문제를 해결하려면 약간의 트릭이 필요하다.
from dataclasses import dataclass, field
@dataclass
class User:
id: str
pw: str
_pw:str = field(init=False)
@property
def pw(self):
return self._pw
@pw.setter
def pw(self, value: str):
self._pw = value
if __name__ == '__main__':
user = User(id='hide', pw='hide123')
print(user.__dict__)
Output: {'id': 'hide', '_pw': 'hide123'}
위처럼 실제로 pw
라는 변수를 추가해주고 _pw
변수에 대해서는 field(init=False)
옵션을 주게되면 dataclass
에 의해 생성자가 생성될 때 _pw
를 생성하지 않는다. 주의할점은, 반드시 setter를 구현해야한다는 것이다. 만약 getter만 구현한다면 오류가 발생할 것이다.
참고 : https://blog.florimond.dev/reconciling-dataclasses-and-properties-in-python
'Coding > Python' 카테고리의 다른 글
Python Alembic으로 Migration 관리하는 방법 (0) | 2019.09.26 |
---|---|
Django Restframework Serializer 뜯어보기 (0) | 2019.09.19 |
Python Requests Retry (0) | 2019.09.05 |
Python Method Chaining (0) | 2019.07.17 |
ECS Blue/Green CodeDeploy 연동 배포 자동화 스크립트 (0) | 2019.06.21 |