Practice/Python, Perl

파이썬 프러퍼티 사용하여 일관되게 속성에 접근하라

파이썬의 프러퍼티(property)를 설명한 책과 글은 많음으로 필요성만 살짝 언급하고 지나가겠다.

파이썬에서는 공개 애트리뷰트(public attribute)을 직접 접근(access)하는 것이 관례이다.

class A:
    def __init__(self):
        self.x = 0

a = A()
a.x = 1
print('{}'.format(a.x))

그런데, 비공개(private) 애트리뷰트[각주:1]가 필요한 경우가 있다.
이들을 외부에서 접근하기 위해서는 엑세스 함수-즉 get_xxx(), set_xxx()와 같은 것-을 사용해야 한다.
접근 형식이 관례와 달아서 표현의 일관성이 깨지는 것이 문제이다.[각주:2]
이럴 때, 프러퍼티를 사용하면 동일한 표현 형식으로 접근이 가능하다.

class A:
    def __init__(self):
        self.x = 0
        self.__y = 0

    @property
    def y(self):
        return self.__y

    @y.setter
    def y(self, value):
        self.__y = value


a = A()
# attribute access
a.x = 1
print('{}'.format(a.x))
# property access
a.y = 2
print('{}'.format(a.y))

아래 코드처럼 엑세스 함수를 사용하면, 즉, a.x와 a.set_y()를 섞어쓰면, 더럽지 아니한가?

class A:
    def __init__(self):
        self.x = 0
        self.__y = 0

    def get_y(self):
        return self.__y

    def set_y(self, value):
        self.__y = value


a = A()
# attribute access
a.x = 1
print('{}'.format(a.x))
# getter/setter access
a.set_y(2)
print('{}'.format(a.get_y()))

매우 드물기는 하지만, 엑세스 함수의 오버라이딩(overriding)이 필요할 때가 있다.
그러한 경우, 아래 예제 코드를 참고하여 작성하도록 한다.[각주:3]

class A:
    def __init__(self):
        pass

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, value):
        self.__x = value


class B(A):
    def __init__(self):
        super().__init__()

    @A.x.setter
    def x(self, value):
        if value < 0:
            raise ValueError('x below 0 is not possible')
        super(B, B).x.__set__(self, value)


class C(B):
    def __init__(self):
        super().__init__()

    @B.x.setter
    def x(self, value):
        if value > 100:
            raise ValueError('x above 100 is not possible')
        super(C, C).x.__set__(self, value)

데코레이션 패턴(decoration pattern)이 상속보다 더 유용할 수 있다.
예를 들면, getter에 캐싱 기능을 추가하는 경우가 그러하다.
데코레이션 패턴으로 구현하는 것은 본 글의 취지와 맞지 않아서 생략한다.


참고 링크:

  1. 관례적으로 '__'로 시작하면 비공개 애트리뷰트이다. [본문으로]
  2. 코드가 더러워진다. [본문으로]
  3. 그 동안의 실무 경험에서 깨달은 한가지 교훈. "때때로 백번의 설명보다 한번의 예제가 낫다." [본문으로]
 [ 1 ]  [ 2 ]  [ 3 ]  [ 4 ]  [ 5 ]  [ 6 ]  [ 7 ]  [ ··· ]  [ 187 ] 

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

카운터

Today : 41
Yesterday : 120
Total : 208,962