[Python] 22. 프로퍼티
본 포스팅은 “윤성우의 열혈 파이썬 중급편” 책 내용을 기반으로 작성되었습니다. 잘못된 내용이 있을 경우 지적해 주시면 감사드리겠습니다.
22-1. 안전하게 접근하기
class Natural:
def __init__(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
def getn(self):
return self.__n
def setn(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
def main():
n = Natural(-3)
print(n.getn())
n.setn(2)
print(n.getn())
main()
(결과) 1
2
위 코드에서 getn 함수는 값 꺼내는 역할, setn 함수는 값 수정하는 역할을 한다.
위와 같이 코드를 짤 경우, 잦은 메소드 호출로 코드가 복잡해 보일 수 있다. 다음 예제 처럼 말이다.
class Natural:
def __init__(self, n):
self.setn(n)
def getn(self):
return self.__n
def setn(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
def main():
n1 = Natural(1)
n2 = Natural(2)
n3 = Natural(3)
n1.setn(n2.getn() + n3.getn())
print(n1.getn())
main()
(결과) 5
메소드가 자주 호출되어서 자칫하면 헷갈릴 수 있을 것 같다. 어떻게 이를 간단해 보이도록 만들 수 있을까? 이때 프로퍼티를 이용해보자!
class Natural:
def __init__(self, n):
self.setn(n)
def getn(self):
return self.__n
def setn(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
n = property(getn, setn)
def main():
n1 = Natural(1)
n2 = Natural(2)
n3 = Natural(3)
n1.n = n2.n + n3.n
print(n1.n)
main()
(결과) 5
n = property(getn, setn) 을 프로퍼티 설정 이라고 한다. 이 코드는 속성 n의 값을 참조하는 경우 getn을 호출해서 반환되는 값을 전달하고, 속성 n에 값을 저장하는 경우에는 setn을 호출하여 그 값을 전달한다! 라는 의미를 갖는다. 이 코드는 property 객체의 생성으로 이어진다!
22-2. property
다음과 같이 property 객체 생성과 함께 getn과 setn 메소드 등록을 별도의 문장으로 진행할 수 있다.
class Natural:
def __init__(self, n):
self.setn(n)
n = property()
def getn(self):
return self.__n
n = n.getter(getn) # getter 등록된 새 property 객체 생성 및 반환
def setn(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
n = n.setter(setn) # setter 등록된 새 property 객체 생성 및 반환
def main():
n1 = Natural(1)
n2 = Natural(2)
n3 = Natural(3)
n1.n = n2.n + n3.n
print(n1.n)
main()
(결과) 5
다음과 같이 프로퍼티에 등록할 메소드 이름을 동일하게 둘 수도 있다.
class Natural:
def __init__(self, n):
self.n = n
def pm(self):
return self.__n
n = property(pm)
def pm(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
n = n.setter(pm)
def main():
n1 = Natural(1)
n2 = Natural(2)
n3 = Natural(3)
n1.n = n2.n + n3.n
print(n1.n)
main()
(결과) 5
22-3. 또 다른 방식
데코레이터 라는 녀석을 기반으로 프로퍼티를 지정할 수 있다. 가장 간결한 방법인데, 데코레이터에 대한 설명은 다음에 설명을 하도록 한다. 예제 부터 보자.
class Natural:
def __init__(self, n):
self.n = n
@property
def n(self):
return self.__n
@n.setter
def n(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
def main():
n1 = Natural(1)
n2 = Natural(2)
n3 = Natural(3)
n1.n = n2.n + n3.n
print(n1.n)
main()
(결과) 5
코드 별로 확인해보자.
@property
def n(self):
return self.__n
요 부분은 property 객체를 생성하면서 바로 다음에 등장하는 메소드를 getter로 지정한다. 그리고 이 property 객체를 n에 저장한다! 즉 다음 코드와 동일하다 볼 수 있다.
def n(self):
return self.__n
n = property(n)
사실 위 코드는 말이 좀 안된다(실제 적용해보면 에러남. 메소드 n에 객체를 저장하다니?). 아무래도 데코레이터 개념을 익혀야 이해할 수 있을 것 같다.
그 다음 코드를 보자.
@n.setter
def n(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
이 부분은 다음 등장하는 메소드를 n 저장된 property 객체의 setter에 등록하며, 이 property 객체를 n에 저장한다. 즉 다음 코드와 동일하다.
def n(self, n):
if(n<1):
self.__n = 1
else:
self.__n = n
n = n.setter(n)
Leave a comment