객체의 속성에 대한 접근을 제어하는 메커니즘을 뜻한다. 기본적으로 디스크립터는 클래스의 속성에 대한 접근을 커스텀하게 제어할 수 있는 특별한 종류의 객체이다. 디스크립터를 통해서 개발자는 속성에 접근하거나 속성을 설정할 때 특정 코드를 자동으로 실행시킬 수 있다.
디스크립터 클래스는 3개의 매직 메서드를 가지고
각 메서드는 공통적으로 self
, obj
파라미터를 가진다.
self
: 디스크립터 클래스를 가리키는 파라미터obj
: 디스크립터가 사용되는 객체(클래스)를 가리키는 파라미터__get__(self, obj, type=None)
: 속성에 접근할 때 실행. type
은 오브젝트의 타입을 말한다.
__set__(self, obj, value)
: 속성을 새 value
값으로 설정할 때 실행.
__delete__(self, obj)
: 속성을 삭제할 때 실행.
class DescriptorEx1(object):
def __init__(self, name = 'Default'):
self.name = name
def __get__(self, obj, objtype):
return "Get method called. -> self : {}, obj : {}, objtype : {}, name : {}".format(self, obj, objtype, self.name)
def __set__(self, obj, name):
print('Set method called.')
if isinstance(name, str):
self.name = name
else:
raise TypeError("Name should be string")
def __delete__(self, obj):
print('Delete method called.')
self.name = None
class Sample1(object):
name = DescriptorEx1()
s1 = Sample1()
# __set__ 호출
s1.name = "Descriptor Test1"
# s1.name = 7 # 예외 발생
# attr 확인
# __get__ 호출
print(s1.name) # Get method called. -> self : <__main__.DescriptorEx1 object at 0x000001E0A5EC1390>, obj : <__main__.Sample1 object at 0x000001E0A5EC1BA8>, objtype : <class '__main__.Sample1'>, name : Descriptor Test1
# __delete__ 호출
del s1.name
# 재확인
# __get__ 호출
print(s1.name) # Get method called. -> self : <__main__.DescriptorEx1 object at 0x000001E0A5EC1390>, obj : <__main__.Sample1 object at 0x000001E0A5EC1BA8>, objtype : <class '__main__.Sample1'>, name : None
property
를 이용한 디스크립터 작성 방식도 있다.
참고
class property(fget=None, fset=None, fdel=None, doc=None)
class DescriptorEx2(object):
def __init__(self, value):
self._name = value
def getVal(self):
return "Get method called. -> self : {}, name : {}".format(self, self._name)
def setVal(self, value):
print('Set method called.')
if isinstance(value, str):
self._name = value
else:
raise TypeError("Name should be string")
def delVal(self):
print('Delete method called.')
self._name = None
name = property(getVal, setVal, delVal, 'Property Method Example.')