질문 배경: 이터러블의 개념은 파이썬에서 목록, 사전, 집합 등의 컬렉션 작업을 통일하기 위해 등장했습니다. 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__에서 생성된 인스턴스에 자신의 상태를 저장합니다.
장점: