property는 외부에서 클래스 내부 변수를 참조하기 위한 함수를 말하는데, 이를 흔히 getter & setter라고도 말한다.
이 때 @property
는 getter, setter를 쉽게 사용할 수 있는 방법을 제공하는 데코레이터이다.
getter, setter는 class의 변수를 직접 참조할 수 없도록 만들기 위한 일종의 장치이다. OOP의 캡슐화에 의해 만들어진 class의 내부 변수를 직접 참조하는 것은 클래스의 변수 관리를 어렵게 만들기 때문이다.
다시 말해, 캡슐화는 class 하나에 그 성질과 기능에 대한 의미를 부여해서 객체로 만드는 것을 뜻하는데 class 내부의 변수는 보호할 필요가 있다. 외부에서 마음대로 변수를 조작할 수 있다면 class를 만들어 사용하는 의미가 없어지는 것이다.
가령, 우리가 자동차를 운전한다고 해서 자동차 내부 기능까지 전부 알아야 하지는 않다. 이처럼 class 역시 필요한 값을 넣으면 해당하는 출력을 받으면 된다. 그 내부 변수는 외부에서 조작할 수 없어야 한다는 것이다.
만약 변수가 변할 수 있는 값이 된다면 class는 기존에 정한 로직대로 작동하지 않게 될 수 있다. 따라서, getter & setter를 이용해 하위 호환성을 높일 수 있을 것이다.
아래는 클래스 내부의 private 변수의 값을 가져오거나 설정하기 위한 방법의 예시이다.
class Greeting():
def __init__(self):
self.__data = "Hi!"
# getter(data 변수 값을 외부에서 받기 위한 getter)
def get_data(self):
return self.__data
# setter(data 변수 값을 외부에서 설정하기 위한 setter)
def set_data(self,data):
self.__data = data
greeting = Greeting()
# getter를 통해 데이터를 받는다.
print(greeting.get_data()) # Hi!
__
(더블 언더스코어)는 변수를 private 하게 만들어 준다.__data
변수에 접근할 수 없다. 따라서 위와 같이 greeting.get_data()
로 접근해야 한다.아래와 같이 getter, setter를 만들어서 접근할 수도 있다.
class Greeting():
def __init__(self):
self.__data = "Hi!"
# getter
@property
def data(self):
return self.__data
# setter(property 이름.setter)
@data.setter
def data(self,data):
self.__data = data
greeting = Greeting()
# getter를 통해 데이터를 받는다.
print(greeting.data) # Hi!
# setter를 통해 데이터를 입력한다.
greeting.data = "Hello!"
# getter를 통해 데이터를 받는다.
print(greeting.data) # Hello!
getter만 선언할 수도 있다. 하지만 setter만 선언할 수는 없다. 당연히 getter가 없으면 데이터를 출력할 수 없기 때문에 setter만 선언할 수는 없을 것이다.
getter만 선언할 경우 읽기 전용 변수가 된다!
class Greeting():
def __init__(self):
self.__data = "Hi!"
# getter
@property
def data(self):
return self.__data
greeting = Greeting()
# getter를 통해 데이터를 받는다.
print(greeting.data) # Hi!
print(greeting.data) # Hi!
greeting.data = "Helloooo~!"
로 선언하려고 하면 에러가 발생한다.위의 예시들에서 Greeting의 attribute인 __data
는 Greeting().__dict__['__data']
로 저장 되어, Greeting 객체의 __data
attribute를 호출할 때 파이썬은 객체의 built-in __dict__
딕셔너리 속성에서 검색해 값을 반환한다.
참고