#-*- python:3.11.4 -*-
파이썬 Class 객체는 프로퍼티 어트리뷰트를 제공하고 있다.
각각 getter, setter, deleter로 get, set, delet 단어 끝에 -er을 붙여 만들어낸 단어로 보인다.
한국어로 하자면 호출명령(불러오기), 편집명령(수정하기), 삭제명령(제거하기) 정도로 번역하면 될 것 같다.
프로퍼티 예제
파이썬 doc에서 제공하는 예제는 다음과 같다.
2개의 예제는 서로 다른 코드처럼 보이지만 수행하는 작업은 동일하다.
예제 2를 기준으로 @property 바로 밑에 있는 함수가 getter, @x.setter 바로 밑에 있는 함수가 setter, @x.deleter 바로 밑에 있는 함수가 deleter가 된다.
# 예제 1
class C:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
# 프로퍼티 선언
x = property(getx, setx, delx, "I'm the 'x' property.")
# 예제 2
class C:
def __init__(self):
self._x = None
@property # getter 선언
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter # setter 선언
def x(self, value):
self._x = value
@x.deleter # deleter 선언
def x(self):
del self._x
프로퍼티 사용방법(호출방법)
사용방법은 별거 없다.
getter로 선언한 함수는 변수처럼 사용할 수 있고, setter로 선언한 함수는 변수값을 변경하는 것처럼 사용하면 된다.
코드를 보면 알겠지만, C class의 x는 변수가 아닌 함수이지만 프로퍼티 어트리뷰트이기 때문에 변수처럼 사용할 수 있는 것을 확인할 수 있다.
deleter의 경우 del 명령을 실행하면 작동한다.
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
if __name__ == '__main__':
a = C()
print(a.x)
a.x = False
print(a.x)
del a.x
print(a.x)
>> None
False
Traceback (most recent call last):
File "c:\seolpyo\example.py", line 20, in <module>
print(a.x)
^^^
File "c:\seolpyo\example.py", line 7, in x
return self._x
^^^^^^^
AttributeError: 'C' object has no attribute '_x'. Did you mean: 'x'?
만약 setter가 없다면?
만약 프로퍼티를 통해 getter만 설정하고 setter를 설정하지 않았다면, getter값을 변경하려고 할 경우 에러가 발생하게 된다.
getter에서 사용하는 변수 n의 값을 변경하는 것은 제대로 적용된다.
코드
class seolpyo:
def __init__(self) -> None:
self.n = '하얀설표'
@property
def name(self):
return self.n
def call(self):
print(f'self.n : {self.n}')
print(f'self.name : {self.name}')
if __name__ == '__main__':
a = seolpyo()
a.call()
a.n = '설표'
a.call()
a.name = 'seolpyo'
a.call()
>> self.n : 하얀설표
self.name : 하얀설표
self.n : 설표
self.name : 설표
Traceback (most recent call last):
File "c:\seolpyo\example.py", line 15, in <module>
a.name = 'seolpyo'
^^^^^^
AttributeError: property 'name' of 'seolpyo' object has no setter
프로퍼티는 언제 사용하게 될까?
프로퍼티는 사용자가 모듈 변수를 임의로 변경하지 못하도록 하고 싶을때 사용하게 된다.
언더바(_)를 파이썬 doc에서는 underscore라고 명명하고 있는데, class 객체 안의 변수명 앞에 2개의 언더스코어를 붙이면 외부에서 변수값을 변경하지 못하게 된다.
다음 예시를 보면 name 변수의 값은 변경이 되지만, 2개의 언더스코어를 붙인 __name 변수의 값은 변경되지 않는 것을 확인할 수 있다.
class seolpyo:
def __init__(self) -> None:
self.__name = '하얀설표'
self.name = '설표'
def call(self):
print(f'self.__name : {self.__name}')
print(f'self.name : {self.name}')
if __name__ == '__main__':
a = seolpyo()
a.call()
a.__name = '설표'
a.name = '하얀설표'
a.call()
>> self.__name : 하얀설표
self.name : 설표
self.__name : 하얀설표
self.name : 하얀설표
변경하지 못하는 값을 변경할 수 있도록 하는 방법
그러나, 상황에 따라 변경하지 못하도록 설정한 변수값을 변경하게 될 때가 있을 것인데, 이때 프로퍼티를 사용하게 된다.
다음과 같이 프로퍼티를 사용해 getter와 setter, deleter를 추가하면 변수값을 변경할 수 있게 된다.
class seolpyo:
# https://white.seolpyo.com/
def __init__(self):
self.__name = '하얀설표'
@property
def name(self):
return self.__name
@name.setter
def name(self, name_new):
self.__name = name_new
return self.__name
@name.deleter
def name(self):
self.__name = 'white seolpyo'
return self.__name
def call(self):
print(f'self.__name : {self.__name}')
print(f'self.name : {self.name}')
if __name__ == '__main__':
a = seolpyo()
a.call()
a.__name = '설표'
a.call()
a.name = '설표'
a.call()
del a.name
a.call()
>> self.__name : 하얀설표
self.name : 하얀설표
self.__name : 하얀설표
self.name : 하얀설표
self.__name : 설표
self.name : 설표
self.__name : white seolpyo
self.name : white seolpyo