파이썬 표준 라이브러리의 collections.abc 모듈은 컨테이너 타입을 위한 다양한 추상 기본 클래스(Abstract Base Class, 이하 ABC)를 제공합니다. 대표적인 클래스로는 Container, Hashable, Iterable, Generator, Set, MutableSet, Awaitable 등이 있습니다.
이 모듈을 사용하려면 먼저 임포트해야 합니다.
import collections.abc
주요 추상 기본 클래스
각 ABC는 고유한 프로토콜, 즉 반드시 구현해야 하는 메서드를 정의합니다. 필요한 메서드만 구현하면 해당 타입처럼 동작하는 클래스를 만들 수 있습니다.
- Container :
__contains__()— in 연산자 지원 - Sized :
__len__()— len() 함수 지원 - Iterable :
__iter__()— for 문 순회 지원 - Hashable :
__hash__()— 딕셔너리 키나 집합 요소로 사용 가능 - Set : 교집합·합집합 등 집합 연산 인터페이스
- MutableSet : add(), discard() 등 변경 가능한 집합
- Awaitable : await 표현식을 지원하는 객체
Set ABC로 집합 컨테이너 만들기
추상 기본 클래스의 강력한 점은 필수 메서드만 구현하면 나머지 연산이 자동으로 제공된다는 것입니다. Set ABC를 상속하면 __contains__(), __iter__(), __len__() 세 가지 메서드만 구현해도 교집합(&), 합집합(|), 차집합(-) 연산과 크기 비교, 동등성 검사까지 그대로 사용할 수 있습니다.
다음 예제는 리스트를 기반으로 중복을 허용하지 않는 커스텀 집합 클래스 ListSet을 구현한 코드입니다.
예제 코드
import collections.abc
class ListSet(collections.abc.Set):
def __init__(self, iterable):
self.elements = lst = list()
for element in iterable:
if element not in lst:
lst.append(element)
def __iter__(self):
return iter(self.elements)
def __contains__(self, value):
return value in self.elements
def __len__(self):
return len(self.elements)
set1 = ListSet('ABCDEF')
set2 = ListSet('DEFGHI')
# & 연산자로 교집합 계산 (Set ABC가 자동 제공)
intersect = set1 & set2
intersect_iter = iter(intersect)
try:
while True:
print(next(intersect_iter))
except StopIteration:
pass
실행 결과
D
E
F
코드 해설
ListSet은 내부적으로 리스트에 요소를 저장하되, 생성 시점에 이미 존재하는 값은 추가하지 않아 집합의 중복 불허 성질을 유지합니다. __iter__(), __contains__(), __len__() 세 메서드만 구현했을 뿐인데도 set1 & set2처럼 교집합 연산자가 정상 동작하는데, 이는 collections.abc.Set이 나머지 집합 연산을 믹스인(mixin) 메서드로 자동 제공하기 때문입니다.
이처럼 추상 기본 클래스를 활용하면 최소한의 코드로 파이썬 내장 컨테이너와 호환되는 커스텀 자료구조를 손쉽게 작성할 수 있습니다.