getitem 메서드는 파이썬의 시퀀스 및 매핑 프로토콜의 일부로 추가되었습니다. 이 마법 메서드를 통해 표준 컬렉션(list, tuple, dict 등)은 인덱스, 키 및 슬라이스에 대한 접근을 지원합니다. 사용자 정의 클래스에서 이 메서드는 객체가 "컬렉션처럼" 작동할 수 있게 합니다.
__getitem__을 구현하지 않으면 사용자 정의 클래스는 인덱싱 및 for 반복을 지원하지 않습니다. 단순 인덱스에만 대한 구현은 슬라이스와 함께 완전히 작동하지 않으며, 인덱스 유형을 무시하면 오류가 발생합니다.
슬라이스와 인덱스를 모두 지원할 수 있도록 __getitem__을 구현하고 이를 처리에서 분리합니다. 이렇게 하면 사용자 정의 객체를 파이썬의 표준 구조에서 사용할 수 있습니다(예: 슬라이스 지원 - your_obj[1:5]).
코드 예제:
class MyRange: def __init__(self, n): self.n = n def __getitem__(self, item): if isinstance(item, int): # 개별 인덱스 if 0 <= item < self.n: return item * 2 raise IndexError('index out of range') elif isinstance(item, slice): # 슬라이스 return [self[i] for i in range(*item.indices(self.n))] else: raise TypeError('Invalid argument type: {}'.format(type(item))) mr = MyRange(10) print(mr[3]) # 6 print(mr[2:5]) # [4, 6, 8]
주요 특징:
__getitem__의 구현만으로 인덱스를 통한 값 할당이 가능해지나요?
아니요. 할당을 지원하려면(your_obj[i] = value) __setitem__을 구현해야 합니다. __getitem__은 오직 읽기를 담당합니다.
__getitem__은 슬라이스에 대해 반드시 리스트를 반환해야 하나요?
아니요. 중요한 것은 클래스의 의미를 고려하여 "시퀀스"를 반환하는 것입니다(같은 유형 또는 튜플을 반환할 수 있음). 이 점이 문제에 적합하게 작동하는 것이 중요합니다.
왜 때때로 TypeError: 'MyClass' 객체는 구독할 수 없습니다라는 오류가 발생하나요?
이 메시지는 my_obj[0]을 실행하려고 할 때 클래스가 __getitem__을 구현하지 않으면 나타납니다. 클래스가 구독 가능하기 위해서는 이 메서드가 필수적입니다.
__getitem__을 int에 대해서만 구현하고 slice를 잊어버림. my_obj[2:5]를 시도하면 TypeError가 발생하고 전체 알고리즘이 중단됨.
장점:
단점:
__getitem__이 슬라이스와 int를 별도로 처리하도록 구현되어 있음. 슬라이스와 인덱스가 정상적으로 작동하며, list(), map(), 반복 메서드가 추가적인 노력 없이 지원됨.
장점:
단점: