프로그래밍파이썬 라이브러리 개발자

파이썬에서 __getitem__ 메서드는 어떻게 작동하며, 이를 구현해야 하는 이유와 슬라이스(slice) 처리 시 고려해야 할 사항은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변.

문제의 역사

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__은 시퀀스 및 반복 가능성 프로토콜의 기초
  • 슬라이스를 지원하려면 slice를 별도로 처리해야 함
  • IndexError와 TypeError 예외는 표준 함수(list(), for 등)의 올바른 작동을 위해 필요함

함정 질문.

__getitem__의 구현만으로 인덱스를 통한 값 할당이 가능해지나요?

아니요. 할당을 지원하려면(your_obj[i] = value) __setitem__을 구현해야 합니다. __getitem__은 오직 읽기를 담당합니다.

__getitem__은 슬라이스에 대해 반드시 리스트를 반환해야 하나요?

아니요. 중요한 것은 클래스의 의미를 고려하여 "시퀀스"를 반환하는 것입니다(같은 유형 또는 튜플을 반환할 수 있음). 이 점이 문제에 적합하게 작동하는 것이 중요합니다.

왜 때때로 TypeError: 'MyClass' 객체는 구독할 수 없습니다라는 오류가 발생하나요?

이 메시지는 my_obj[0]을 실행하려고 할 때 클래스가 __getitem__을 구현하지 않으면 나타납니다. 클래스가 구독 가능하기 위해서는 이 메서드가 필수적입니다.

일반적인 오류 및 안티 패턴

  • int만 확인하고 slice를 무시함: 슬라이스는 항상 오류로 발생함
  • 잘못된 유형 반환(예: 슬라이스에서 시퀀스 대신 None 반환)
  • IndexError를 발생시키지 않아 for 루프가 올바르게 작동하지 않음

실제 예

부정적 사례

__getitem__을 int에 대해서만 구현하고 slice를 잊어버림. my_obj[2:5]를 시도하면 TypeError가 발생하고 전체 알고리즘이 중단됨.

장점:

  • 단순성

단점:

  • 슬라이스를 지원하지 않아서 코드는 대부분의 표준 구조와 호환되지 않음

긍정적 사례

__getitem__이 슬라이스와 int를 별도로 처리하도록 구현되어 있음. 슬라이스와 인덱스가 정상적으로 작동하며, list(), map(), 반복 메서드가 추가적인 노력 없이 지원됨.

장점:

  • 클래스가 파이썬의 표준 도구와 호환됨
  • 인덱스의 다양한 유형(튜플, 행렬의 str 등)에 대해 쉽게 확장 가능함

단점:

  • 구현에 조금 더 많은 코드와 테스트가 필요함