[Python] Property Extension
deleter
지난번에 Python에서 접근 지정을 위해 property class를 사용한다고 배웠다. Property 기능은 크게 세 가지가 존재하는데, getter, setter, deleter가 존재한다.
deleter는 property를 삭제할 때 호출되는 함수다. (del을 통해)
Subclass에서 Property
class Person:
def __init__(self, name):
self.name = name # 실제 호출은 setter property가 호출됨
# 따라서 name의 저장은 self._name 에 저장됨
@property
def name(self):
return self._name
# name = property(name)
@name.setter
def name(self, value):
if not isinstance(value, str):
raise TypeError('Expected a string')
self._name = value
@name.deleter
def name(self):
raise AttributeError("Can't delete attribute")
class SubPerson(Person):
@property
def name(self):
print('Getting name')
return super().name
@name.setter
def name(self, value):
print('Setting name to', value)
super(SubPerson, SubPerson).name.__set__(self, value)
@name.deleter
def name(self):
print('Deleting name')
super(SubPerson, SubPerson).name.__delete__(self)
if __name__ == '__main__':
a = SubPerson('Guido')
print(a.name)
a.name = 'Dave'
print(a.name)
try:
a.name = 42
except TypeError as e:
print(e)
| Setting name to Guido Getting name Guido Setting name to Dave Getting name Dave Setting name to 42 Expected a string |
Subclass에서 super class의 멤버를 호출하기 위해서 super의 getter, setter를 호출하면 된다. 참고로 __set__과 __delete__는 super class의 setter와 deleter를 각각 호출한다.
super(SubPerson, SubPerson).name.__set__(self, value) 에서 super()의 인자는 다음과 같다.
super([Subclass Name], [Subclass Type] or [Subclass Instance Type])
실제 우리가 접근하고자 하는 getter와 setter는 모두 instance 변수 (self.* 가 붙는 형식)가 아닌 class 변수 (self.* 가 붙지 않는 형식) 이다. 만약 instance type이면 생략이 가능하다.
위 코드에선 super().name 으로 name이 class 변수기 때문에 super()의 두 번째 인자는 class type (SubPerson)이 들어가야한다.
부모의 메소드에 도달하기 위한 유일한 방법은 instance 변수가 아닌 class 변수로 접근해야 한다.