Intro
안녕하세요, 지난글에서는 python의 decorator에 대해서 간단히 살펴봤습니다.
이번 글에서는 python에서 기본으로 제공해주면서 많이 쓰이는 @property
decorator에 대해서 정리하겠습니다.
@property
@property
decorator는 많은 분들이 private 변수의 getter, setter를 설정하기 위해서 많이 사용한다고 해서, 그 용도로만 쓰이는 건줄 알았습니다. 하지만 조금 더 알아본 결과, 제가 생각하는 @property
decorator의 본질은 "function(함수)을 variable(변수)처럼 사용하기" 입니다.
예를 들면 아래와 같습니다.
class PropertyTest():
@property
def func_with_property(self):
print("called with property")
def func_without_property(self):
print("called without property")
if __name__ == "__main__":
pt = PropertyTest()
tc.func_with_property
## output: called with property
tc.func_without_property
## output: <bound method PropertyTest.func_without_property of <__main__.PropertyTestClass object at 0x0000016FC1D827F0>>
tc.tc.func_without_property()
## output: called without property
위의 예시를 보시면, @property
를 위에 적은 func_with_property
를 호출할 때는 ()
를 안붙여도 그 반환값을 알 수 있습니다.
이러한 특성을 활용해서 private 변수의 getter, setter를 설정할 수 있는 겁니다.
우선 python에서도 private 변수를 설정할 수 있는 걸 모르는 분이 있을 수 있는데요, 변수이름 앞에 __
또는 _
를 붙여서 외부로부터 접근을 제어할 수 있습니다. 그래서 private 변수에 접근하기 위한 getter와 setter가 필요한 것이죠.
python의 private 변수와 관련한 내용은 따로 다루도록 하겠습니다.
먼저 일반적인 getter, setter를 이용한 private 변수와 public 변수로의 접근을 비교해보겠습니다.
class GetterSetterWithFunc():
def __init__(self, pri_var, pub_var):
self.__pri_var = pri_var
self.pub_var = pub_var
def get_pri_var(self):
return self.__pri_var
def set_pri_var(self, pri_var):
self.__pri_var = pri_var
if __name__ == "__main__":
gswf = GetterSetterWithFunc(1, 10)
gswf.__pri_var
## output: AttributeError
gswf.pri_var
## output: AttributeError
gswf.get_pri_var()
## output: 1
gswf.set_pri_var(100)
gswf.get_pri_var()
## output: 100
gswf.pub_var
## output: 10
gswf.pub_var = 1000
gswf.pub_var
## output: 1000
위의 예시와 같이, private 변수인 pri_var
는 get_pri_var()
나 set_pri_var()
을 통해서만 접근이 가능한 반면, public 변수인 pub_var
은 바로 접근이 가능합니다.
그런데, private 변수와 public 변수를 다룰 때 이를 구분해서 사용하기 불편하기도 하죠, @property
decorator를 사용하면 private, public상관없이 다룰 수 있습니다. 어떻게 달라지는지 보겠습니다.
class GetterSetterWithProperty():
def __init__(self, pri_var, pub_var):
self.pri_var = pri_var
self.pub_var = pub_var
@property
def pri_var(self):
return self.__pri_var
@pri_var.setter
def pri_var(self, pri_var):
self.__pri_var = pri_var
if __name__ == "__main__":
gswp = GetterSetterWithProperty(1, 10)
gswp.pri_var
## output: 1
gswp.pri_var = 100
gswp.pri_var
## output: 100
gswp.pub_var
## output: 10
gswp.pub_var = 1000
gswp.pub_var
## output: 1000
이와 같이, @property
를 사용하면 private, public 변수를 같은 방법으로 다룰 수 있게 됩니다. 다만 차이점이 있다면, __init__()
에서 호출되는 self.pri_var
는 변수가 아닌 아래에 정의된 pri_var
function이고, private 변수인 pri_var
는 해당 function을 실행할 때 생성 됩니다. 반면 pub_var
는 __init__()
에서 바로 생성됩니다.
마무리
오늘은 python의 기본 decorator 중 하나인 @property
decorator에 대해서 정리해봤습니다. 다음 글에서는 @staticmethod
, @classmethod
에 대해서 정리하겠습니다.
글 읽어주셔서 감사합니다!
'[Python]' 카테고리의 다른 글
[Python] timeit 모듈과 pandas함수들의 속도 비교 테스트 (0) | 2021.07.18 |
---|---|
[Python] Mixin 이란? (0) | 2021.07.10 |
[Python] Decorator(4) - dataclass, functools (0) | 2021.07.04 |
[Python] Decorator(3) - @classmethod, @staticmethod (0) | 2021.06.28 |
[Python] Decorator(1) - decorator란? (0) | 2021.06.15 |