반응형
보통 자바와 같은 언어에 익숙한 사람이라면, 아래와 같이 getter / setter 함수에 익숙할 것이다.
class OldResistor:
def __init__(self, ohms):
self._ohms = ohms
def get_ohms(self):
return self._ohms
def set_ohms(self, ohms):
self._ohms = ohms
이렇게 setter와 getter를 사용하는 것은 다음과 같이 사용할 수 있다.
r0 = OldResistor(50e3)
r0.set_ohms(10e3)
r3.set_ohms(r0.get_ohms() + 5e3)
간단하고, 클래스의 인터페이스를 정의하는데 도움이 되고, 사용법을 검증할 수 있게 하고, 경계를 정의하기 쉽게 해준다.
그러나 파이썬 답지 않다.
아마 아래와 같이 쓸 수 있으면, 좀 더 심플하고, 명확하고, 따라서 파이썬다워 질 것 같다.
(setter, getter를 쓰지 않고, 해당 속성에 직접 접근)
r1 = Resistor(50e3)
r1.ohms = 10e3
r1.ohms += 5e3
만약 setter, getter에서 사용법을 검증하는 것과 같이, 속성을 설정할 때 (혹은 읽어올 때) 특별한 동작이 일어나야 한다면,
@property 데코레이터와 이에 대응하는 setter 속성을 사용하면 된다.
class NewResistor:
def __init__(self, ohms):
self._ohms = ohms
@property
def ohms(self):
return self._ohms
@ohms.setter
def ohms(self, ohms):
if ohms <= 0:
raise ValueError(f'{ohms} ohms must be > 0')
self._ohms = ohms
참고로, 속성을 불변(immutable)으로 만들 때도 @property를 사용할 수 있다.
class FixedResistor:
def __init__(self, ohms):
self._ohms = ohms
@property
def ohms(self):
return self._ohms
@ohms.setter
def ohms(self, ohms):
if hasattr(self, ohms):
raise AttributeError("Can't set attribute")
self._ohms = ohms
해당 객체를 생성하고 나서 속성에 새로운 값을 할당하려고 하면 예외가 일어날 것이다.
r2 = FixedResistor(1e3)
r2.ohms = 2e3
>>>
AttributeError: Can't set attribute
반응형
'Programming Language > Python' 카테고리의 다른 글
Effective Python. 지연 속성에는 __getattr__, __getattribute__, __setattr__을 사용하자. (0) | 2021.03.02 |
---|---|
Effective Python. 재사용 가능한 @property 메서드에는 디스크립터를 사용하자. (0) | 2021.03.02 |
Effective Python. 메타클래스와 속성 (0) | 2021.03.02 |
[파이썬/Python] List 형태의 String을 List로. List 형태의 Dict를 Dict로. (1) | 2020.05.21 |
파이썬 메타클래스 쉽고 깊게 이해하기, Python Metaclass A to Z (3) | 2020.03.16 |