스페셜 메소드로 iterable, iterator 객체 만들기

YangJiWon·2020년 9월 8일
0

python

목록 보기
12/12

개요

  • iterable 객체 : iter 함수에 인자로 전달 가능한 객체, 그 결과로 'iterator 객체' 반환
  • iterator 객체 : next 함수에 인자로 전달 가능한 객체

그렇다면 iterable 객체가 되기 위한 조건과 iterator 객체가 되기 위한 조건은 무엇일까?

  • iterable 객체의 조건 : 스페셜 메소드인 __iter__가 존재해야 합니다.
  • iterator 객체의 조건 : 스페셜 메소드인 __next__가 존재해야 합니다.

iterable 객체 만들기

다음 예제는 한 클래스를 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
  • 위의 예제에서 Car클래스에 iter 메소드를 넣어줌으로써 iterable객체가 되도록 하였습니다.
  • 위의 메소드가 반환하는 iterator 객체는 self.id의 iterator 객체입니다.

iterator 객체가 되게끔 하기

  • iterator객체의 조건은 스페셜 메소드인 __next__가 존재해야 합니다.
    물론 이 메소드를 갖기만 하는 것이 아니라 실제 iterator객체로 사용할 수 있는 수준으로 메소드가 정의되어야 합니다.

  • 따라서 다음 두 조건을 기본적으로 만족시켜야 합니다.

  1. 가지고 있는 값을 하나씩 반환합니다.
  2. 더 이상 반환할 값이 없는 경우 StopIteration 예외를 발생시킵니다.
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()
  • 위의 예제는 클래스를 iterator 객체로 만드는 예제입니다.

iterator 객체이자 iterable 객체로 만들기

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 함수의 호출 횟수가 0으로 초기화되어 첫 번째 값부터 다시 반환이 이루어지도록 코드를 작성했기 땜누에 iter 함수는 몇 번이고 호출할 수 있습니다.

정리

  • iterable 객체의 조건 : 스페셜 메소드인 __iter__가 존재해야 합니다.
  • iterator 객체의 조건 : 스페셜 메소드인 __next__가 존재해야 합니다.
  • iterator의 경우 추가적인 조건이 두 개 더 붙습니다.
  1. 가지고 있는 값을 하나씩 반환합니다.
  2. 더 이상 반환할 값이 없는 경우 StopIteration 예외를 발생시킵니다.
profile
데이터데이터데이터!!

0개의 댓글