[Python] 프로퍼티

2 분 소요

property

class Natural:       # 자연수를 표현한 클래스
    def __init__(self, n):
        self.setn(n)       # 아래에 있는 setn 메소드 호출

    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     # n2와 n3의 덧셈 결과를 n1에 저장
    print(n1.n)
    
main()
5

객체가 갖는 값에 직접 접근하는 것은 오류의 확률을 높이므로 메소드를 통해 접근하는 것이 안전하다.

이때 메소드를 구현하는데, 메소드를 계속 사용하면 코드가 복잡해진다. 그래서 프로퍼티를 설정해 간결하게 사용할 수 있다.

n = property(getn, setn) 다음 코드는 속성 n의 값을 참조하는 경우에 getn을 호출해 반환되는 값을 전달하겠다는 의미이고, 속성 n에 값을 저장하는 경우에는 setn을 호출해 그 값을 전달하겠다는 의미이다.

n = property(getn, setn) 문장은 변수 n에 property 객체를 생성해 저장한다.

class Natural:       # 자연수를 표현한 클래스
    def __init__(self, n):
        self.setn(n)       # 아래에 있는 setn 메소드 호출

    n = property()       # property 객체 생성
    
    def getn(self):
        return self.__n
    n = n.getter(getn)       # getn을 게터로 등록
    
    def setn(self, n):
        if(n < 1):
            self.__n = 1
        else:
            self.__n = n    
    n = n.setter(setn)       # setn을 세터로 등록


def main():
    n1 = Natural(1)
    n2 = Natural(2)
    n3 = Natural(3)
    
    n1.n = n2.n + n3.n     # n2와 n3의 덧셈 결과를 n1에 저장
    print(n1.n)
    
main()
5

위 코드처럼 property 객체 생성과 등록은 setter, getter로 따로 진행할 수 있다.

class Natural:       # 자연수를 표현한 클래스
    def __init__(self, n):
        self.n = n       # 프로퍼티 n을 통해 접근

    n = property()       # property 객체 생성
    
    def pm(self):
        return self.__n
    n = n.getter(pm)       # 위의 pm을 게터로 등록
    
    def pm(self, n):
        if(n < 1):
            self.__n = 1
        else:
            self.__n = n    
    n = n.setter(pm)       # 위의 pm을 세터로 등록


def main():
    n1 = Natural(1)
    n2 = Natural(2)
    n3 = Natural(3)
    
    n1.n = n2.n + n3.n     # n2와 n3의 덧셈 결과를 n1에 저장
    print(n1.n)
    
main()
5

프로퍼티를 등록하고 나면 사실상 getn, setn과 같은 이름은 사용할 이유가 없다. 그래서 위 예제처럼 프로퍼티에 등록할 메소드의 이름을 동일하게 두는 경우도 있다.

프로퍼티를 설정한 후에는 한가지 방법으로만 변수에 접근하여 혼란을 줄일 필요가 있다. 즉 메소드의 이름을 통해 변수에 접근하는 일을 피해야 하기때문에 위 코드와 같이 프로퍼티에 등록할 세터와 게터의 이름을 동일하게 두는 경우가 매우 흔하다.

데코레이터를 이용한 방식

class Natural:       # 자연수를 표현한 클래스
    def __init__(self, n):
        self.n = 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

데코레이터를 기반으로 프로퍼티를 지정하는 방법도 있다. 보다 간결하다. 그래서 데코레이터 방식이 더 많이 쓰인다.