그렇다면 iterable 객체가 되기 위한 조건과 iterator 객체가 되기 위한 조건은 무엇일까?
__iter__
가 존재해야 합니다.__next__
가 존재해야 합니다.다음 예제는 한 클래스를 iterable 객체가 되게끔 만드는 예제입니다.
class Car:
def __init__(self, id):
self.id = id
def __iter__(self): # 스페셜 메소드
return iter(self.id) # 변수 id의 iterator 객체를 반환
def main():
c = Car("325234")
for i in c: # Car 객체가 iterable 객체라는 증거
print(i, end = ' ')
main()
# 3 2 5 2 3 4
iterator객체의 조건은 스페셜 메소드인 __next__
가 존재해야 합니다.
물론 이 메소드를 갖기만 하는 것이 아니라 실제 iterator객체로 사용할 수 있는 수준으로 메소드가 정의되어야 합니다.
따라서 다음 두 조건을 기본적으로 만족시켜야 합니다.
class Col1:
def __init__(self, d):
self.ds = d # 인자로 전달된 값을 저장합니다.
self.cc = 0 # __next__ 메소드 호출 횟수
def __next__(self):
if len(self.ds) <= self.cc:
raise StopIteration
self.cc += 1
return self.ds[self.cc - 1]
def main():
co = Col1([1, 2, 3, 4, 5])
while True:
try:
i = next(co)
print(i, end = ' ')
except StopIteration:
break
main()
class Col2:
def __init__(self, d):
self.ds = d # 인자로 전달된 값을 저장합니다.
def __next__(self):
if len(self.ds) <= self.cc:
raise StopIteration
self.cc += 1
return self.ds[self.cc - 1]
def __iter__(self):
self.cc = 0
print('__iter__ call')
return self
def main():
co = Col2([1, 2, 3, 4, 5])
for i in co:
print(i, end = ' ')
for i in co:
print(i, end = ' ')
main()
위 예제에서 iter 메소드를 관심있게 봐야 합니다.
Col2객체는 그 자체로 __next__
메소드를 갖는 iterator 객체입니다.
즉, Col2 객체는 __next__
메소드를 갖는 iterator 객체이자 동시에 __iter__
메소드를 갖는 iterable 객체입니다.
그래서 col2의 __iter__
메소드는 self를 반환합니다.
그리고 self의 반환 결과는 위 클래스 col2를 대상으로 다음 코드를 실행해 봄으로써 확인할 수 있습니다.
co = col2('hello')
itr = iter(co)
itr is co # True
__iter__
가 존재해야 합니다.__next__
가 존재해야 합니다.