컨테이너: 함수와 애트리뷰트를 함께 캡슐화
데이터 관리
#빈도 계산
"""
리스트의 하위 클래스를 만들어서 리스트가 제공하는 모든 표준함수 사용 가능
"""
class FrequencyList(list):
def __init__(self, members):
super().__init__(members)
def frequency(self):
counts = {}
for item in self:
counts[item] = counts.get(item, 0) + 1
return counts
#위의 클래스를 활용하면 필요한 기능을 제공하는 메서드 추가 가능
foo = FrequencyList(['a','b','a','c','b','a','d'])
print('길이:',len(foo))
foo.pop()
print('pop한 다음:', repr(foo))
print('빈도:', foo.frequency())
#인덱싱이 가능하지만 리스트의 하위 클래스는 만들기 싫다.
class BinaryNode:
def __init__(self, value, left=None, right=None):
self.value =value
self.left = left
self.right = right
"""
BinaryNode 클래스가 시퀀스처럼 작동하려면 트리 노드를 깊이 우선 순회하는
커스텀 __getitem__메서드 구현 제공
"""
class IndexableNode(BinaryNode):
def _traverse(self):
if self.left is not None:
yield from self.left._traverse()
yield self
if self.right is not None:
yield from self.right._traverse()
def __getitem__(self, index):
for i , item in enumerate(self._traverse()):
if i == index:
return item.value
raise IndexError(f'인덱스 범위 초과: {index}')
추가 사항
올바른 시퀀스를 형성하기 위해서 getitem과 len으로는 부족하다.
즉, 자신만의 컨테이너 타입을 직접 정의하는 것은 그만큼 어렵다.