프로그래밍백엔드 개발자

파이썬에서 이터러블 객체란 무엇이며, 사용자 정의 이터러블 객체를 올바르게 구현하는 방법은 무엇인가요?

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

답변

질문 배경: 이터러블의 개념은 파이썬에서 목록, 사전, 집합 등의 컬렉션 작업을 통일하기 위해 등장했습니다. for 루프를 통해 반복할 수 있는 모든 객체는 이터러블로 간주됩니다. 이는 특정 매직 메서드를 통해 구현됩니다.

문제: 파이썬은 시퀀스와 관련된 루프 및 함수가 올바르게 작동하려면 특정 프로토콜을 요구합니다. 사용자가 클래스에서 이러한 프로토콜을 잘못 구현하면 표준 메커니즘(for, list(), sum() 등)이 작동하지 않거나 예상치 못한 방식으로 동작할 수 있습니다.

해결책: 이터러블 객체는 __iter__ 메서드를 구현하는 객체입니다. 이터레이터는 __next____iter__가 있으며, 후자는 self를 반환합니다. 일반적으로 __iter__가 반환하는 객체는 이터레이터이지만 반드시 그런 것은 아닙니다. 예:

class MyRange: def __init__(self, start, end): self.start = start self.end = end def __iter__(self): self.current = self.start return self def __next__(self): if self.current < self.end: val = self.current self.current += 1 return val raise StopIteration for x in MyRange(1, 4): print(x) # 1, 2, 3

주요 특징:

  • 이터러블은 __iter__ 메서드의 존재로 정의됩니다.
  • 이터레이터는 __next____iter__(self를 반환하는)를 모두 구현해야 합니다.
  • __iter__에서 새로운 객체를 반환하는 것은 컬렉션에 대한 여러 독립적인 반복이 필요할 때 효과적으로 구현됩니다.

함정 질문

모든 이터러블 객체에 __next__ 메서드가 반드시 필요한가요?

아니요. 이터러블 객체에는 이터레이터를 반환하는 __iter__만 필요합니다. __next__는 오직 이터레이터에서만 구현됩니다. 예를 들어, list는 __next__ 메서드가 없지만, 이터러블입니다: 그 __iter__는 이터레이터의 인스턴스를 반환합니다.

lst = [1, 2, 3] print(hasattr(lst, '__next__')) # False

객체가 스스로 이터레이터가 될 수 있나요?

네, 두 메서드인 __iter____next__를 모두 구현한다면 가능합니다.

한 컬렉션에 대해 독립된 상태를 가진 여러 이터레이터를 생성할 수 있을까요?

네, __iter__가 매번 새로운 이터레이터 객체를 반환한다면 가능합니다.

class MyList: def __init__(self, data): self.data = data def __iter__(self): return iter(self.data)

일반적인 오류 및 안티 패턴

  • __iter__ 없이 __next__만 구현하거나 그 반대입니다.
  • 클래스 수준이 아니라 인스턴스 수준에서 상태를 기억하여 반복 시 버그가 발생합니다.

실제 예시

부정적인 케이스: 이터레이터 클래스가 상태(예: 현재 인덱스)를 클래스 수준에서 저장하여 병렬 반복이 서로 충돌하는 경우입니다. 장점:

  • 메모리 절약(단 하나의 인덱스만). 단점:
  • 두 개의 루프에서 동시에 반복할 때 오류 발생.

긍정적인 케이스: 각 이터레이터가 __iter__에서 생성된 인스턴스에 자신의 상태를 저장합니다. 장점:

  • 여러 이터레이터가 올바르게 작동합니다. 단점:
  • 메모리 소모가 소소하게 증가합니다.