데이터를 처리할 땐 반복은 기본이며 메모리에 다 들어가지 않는 데이터셋을 검색할 때는 항목들을 느긋하게 가져와야 하므로 한 번에 하나씩 필요할 때 가져와야 합니다.(반복자 패턴)
파이썬은 리스프와 달리 매크로가 없기에 반복자 패턴을 추상화할 수 있게 yield 키워드가 파이썬 2.2에 추가되었다.
클래스의 생성자는 텍스트로 구성된 문자열 받은 후 단어별로 반복하고, 시퀀스 프로토콜을 구현하면서 반복
#sentence.py: 단어 시퀀스로서의 Sentence 클래스
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence:
def __init__(self, text):
self.text =text
self.words = RE_WORD.findall(text)
def __getitem__(self, index):
return self.words[index]
def __len__(self):
return len(self.words)
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text)
Sequence가 반복 가능한 이유: iter()함수
파이썬 인터프리터 x 객체를 반복해야 할 땐 언제나 iter(x)를 자동으로 호출한다.
객체가 iter() 메서드를 구현하는지 확인하고, 이 메서드를 호출해서 반복자를 가져온다.
iter() 메서드가 구현되어 있지 않지만 getitem()이 구현되어 있다면, 파이썬은 인덱스0에서 시작해서 항목을 순서대로 가져오는 반복자를 생성한다.
이 과정이 모두 실패하면 파이썬은 "TypeError:'C' object is not iterable'이라는 메시지와 함께 TypeError가 발생한다.
그러므로, 모든 파이썬 시퀀스는 반복이 가능하고 이 이유는 시퀀스가 getitem()을 구현하고 있기 때문이며 표준 시퀀스는 iter()메서드도 구현하고 있기에 정의한 시퀀스도 이 메서드를 구현해야 한다.
"""
구스 타이핑 기법을 사용하면 반복형에 대한 정의가 단순해질 수 있지만, 융통성이 떨어져서 __iter__() 특별 메서드를 구현하는 객체만 반복형이라고 간주하고, abc.Iterable 클래스가 __subclasshook__() 메서드를 구현하고 있으므로 상속이나 등록은 필요 없다.
"""
class Foo:
def __iter__(self):
pass
from collections import abc
issubsclass(Foo, abc.Iterable)
f= Foo()
isinstance(f, abc.Iterable)