http://meonggae.blogspot.kr/2016/11/python-getter-setter-property-setter.html
필자가 전에 한번 getter와 setter에 관련되서 글을 쓴 적이 있다.
이때 getter와 setter함수를 구현하지 말고 @property를 이용해서 구현을 하라고 했다
하지만 코드를 작성하다보면 @property가 복잡해지는 경우가 발생을 할 것이다. 이럴떄는 descriptor를 사용을 하여 코드를 좀더 깔끔하게 할 수 있다.
class test:
@property
def t(self):
return self._t
@t.setter
def t(self, value):
print('setter 작동')
self._t = 10
a = test()
a.t = 10
property를 이용하여 코드를 작성을 할 수 있습니다.property를 이용하영 외부에서 _t를 접근 할 수 있도록 하였습니다.
$ python3 app.py
setter 작동
외부에서 t를 접근 할 때 정상적으로 t()가 실행 됬음을 확인 할 수 있습니다.그런데 이는 외부 뿐 아니라 내부에서 접근을 할 때에도 실행이 됩니다.
class test:
def __init__(self):
self.t = 1
@property
def t(self):
return self._t
@t.setter
def t(self, value):
print('setter 작동')
self._t = 10
a = test()
a.t = 10
해당 코드를 실행을 시켜봅시다.
$ python3 app.py
setter작동
setter작동
t()가 두번 실행됬습니다.test()에서 __init__이 호출이 되면서 내부적으로 self._t = 1에서 호출이 되고
외부에서 a = 10에서 한번 호출이 됩니다.
그런데 만약 property설정이 많아진다면 어떻게 될까요
class test:
def __init__(self):
self.t = 1
@property
def t(self):
return self._t
@t.setter
def t(self, value):
print('setter 작동')
self._t = 10
@property
def a(self):
return self._a
@a.setter
def a(self, value):
print('setter 작동')
self._a = 10
@property
def b(self):
return self._b
@b.setter
def b(self, value):
print('setter 작동')
self._b = 10
a = test()
a.t = 10
속성마다 직접 구현을 해주어야 합니다. 근데 만약 내부적으로 코드가 같다면 상당히 비효율적으로 작성이 될 것입니다.
이럴때는 descriptor를 이용하면 매우 효율적인 코드작성이 가능합니다.
__set__, __get__를 이용 할 것입니다.
class t(object):
def __get__(*args, **kwargs):
print('get')
def __set__(*args, **kwargs):
print(**kwargs)
print('set')
class test():
a = t()
b = t()
a = test()
a.a = 10
a.b = 20
위에서 property로 나열 했던 코드를 descriptor를 이용하여 심플하게 바꾸어 보았습니다.object의 디스크립터를 이용하여 해당 클래스를 object처럼 사용이 가능 해졌습니다.
위처럼 t클래스는 object로 부터 상속을 받아 object의 메소드들을 오버라이딩 하여 재 정의가 가능해지면서 모든것을 그대로 사용 할 수 있게 됩니다.
$ python3 app.py
set
set
댓글
댓글 쓰기