https://docs.python.org/3/tutorial/classes.html#iterators
for 루프는 내부적으로 컨테이너에 iter()를 호출하고, 반환된 이터레이터의 __next__를 반복 호출하다가 StopIteration이 나오면 종료합니다.
이터레이터 프로토콜을 직접 구현하려면:
__iter__(self)에서 이터레이터 객체를 반환(보통 self).__next__(self)에서 다음 값을 반환하고, 더 없으면 StopIteration을 raise.
예시처럼 Reverse는 문자열을 뒤집어 순회하기 위해 index를 감소시키다가 0이 되면 StopIteration을 던집니다.
class Reverse:
"""뒤에서 앞으로 순회하는 이터레이터"""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self # 자기 자신이 이터레이터
def __next__(self):
if self.index == 0:
raise StopIteration
self.index -= 1
return self.data[self.index]
rev = Reverse("spam")
for ch in rev:
print(ch)
# 출력: m a p s필요하다면, “이터러블과 이터레이터를 분리”한 형태도 이렇게 만들 수 있습니다:
class ReverseIterable:
def __init__(self, data):
self.data = data
def __iter__(self):
return ReverseIterator(self.data)
class ReverseIterator:
def __init__(self, data):
self.data = data
self.idx = len(data)
def __iter__(self):
return self
def __next__(self):
if self.idx == 0:
raise StopIteration
self.idx -= 1
return self.data[self.idx]
for ch in ReverseIterable("spam"):
print(ch)for 루프는 내부적으로 컨테이너에 iter()를 호출하고,
반환된 이터레이터의 __next__를 반복 호출하다가
StopIteration이 나오면 종료하기 때문에 이렇게 구현이 가능