본문 바로가기

프로그래밍/파이썬

[파이썬] get/set 속성값과 프로퍼티(property)

get, set 프로퍼티

0. 들어가기 전에

이번에 다룰 내용은 객체의 속성(attribute)을 다루는 주제로 포스팅할 것입니다.

오늘 배울 getter메서드와 setter 메서드는 객체의 변수(속성)를 읽고, 변경하는데 사용합니다.

TIP : 객체(Object) = 속성(attribute) + 기능(Method)

1. get/set 속성값과 프로퍼티의 개념

자바와 같은 객체 지향 언어에서는 외부로부터 바로 접근할 수 없는 prviate 객체 속성을 지원합니다.
이러한 언어에서는 private 속성의 값을 읽고(get) 변경(set)하기 위해 getter 메서드와 setter 메서드를 사용합니다.

하지만, 파이썬에는 getter 메서드나 setter메서드가 없습니다.
파이썬에서 선언되는 모든 속성(변수)와 메서드는 public이기 때문입니다.

파이썬에서는 사용자가 속성에 직접 접근을 막기 위해 getter 또는 setter 메서드 대신에 프로퍼티(property) 를 사용합니다.

들어가기 전에 : 변수명에 홑밑줄(_)과 겹밑줄(__)이 있습니다.

  • 홑밑줄(single underscore) : 보통 내부적으로 사용하는 변수일 때 사용합니다.

  • 곁밑줄(double underscore) : 클래스 외부에서 접근할 수 없도록 내부 변수로 만듭니다.

2. get/set 속성값과 프로퍼티 예제

예제를 먼저 살펴보도록 하겠습니다.

class Movie:
    def __init__(self, movie_name):
        self.__movie_name = movie_name
 
    @property
    def movie_name(self): # 이때 메서드 이름은 변수(속성)의 이름과 동일하게 하는 것이 좋습니다. 
        return self.__movie_name
 
    @movie_name.setter
    def movie_name(self, new_movie_name): # 이때 메서드 이름은 변수(속성)의 이름과 동일하게 하는 것이 좋습니다. 
        """ 영화를 변경하는 setter 메서드"""
        self.__movie_name = new_movie_name
        print("============ setter를 통해 영화를 변경합니다============")
        print('변경 후 영화이름 : {} '.format(self.movie_name))

movie_name 위에 @가 붙은 것을 볼 수 있습니다.
이를 데커레이터(decorator)라고 하는데, 말그대로 뭔가를 꾸며 주는 함수를 의미합니다.
비록 같은 movie_name 이름을 갖는 메서드이지만 장식자 @에 의해 서로 다른 역할을 합니다.

movie = Movie('총알 탄 사나이')
print(movie.movie_name)
movie.movie_name = '히든 피겨스' # 객체의 속성값에 직접 접근하는듯이 사용하지만 
                               # 실제로는 메서드 호출을 통해 변수에 접근한다. 
print(movie_movie_name)
 
>>> 출력결과
> 총알 탄 사나이
> ============ setter를 통해 영화를 변경합니다============
> 변경 후 영화이름 : 히든 피겨스
> 히든 피겨스

만약 프로퍼티가 없었다면 영화이름을 아래처럼 불편하게 변경해줬어야 할지도 모르겠습니다.
property를 이용하면 클래스 정의에 있는 코드만 수정하면 손쉽게 속성을 변경할 수 있습니다.

> 기존 코드
> movie = Movie('총알 탄 사나이')
> movie = Movie('히든 피겨스') # 속성을 변경하려면 호출자를 다시 수정해야 한다. 
 
> 개선된 코드
> movie = Movie('총알 탄 사나이')
> movie.movie_name = '히든 피겨스'

property

만약 setter 프로퍼티를 명시하지 않으면 읽기전용(read-only)이 되어 외부에서 값을 변경할 수 없습니다.
setter 프로퍼티를 주석처리하면 can't set attribute의 출력결과를 얻습니다.

참조

  1. Introducing Python 180~185p

  2. http://egloos.zum.com/nemonein/v/5280842