WeniVooks

검색

파이썬 클래스 톺아보기

매직 메서드 - 반복

1. 반복 가능한 객체

파이썬에서는 for 루프를 만나면 해당되는 객체의 __iter__를 실행합니다. 그리고 __next__를 순차적으로 실행합니다. 이를 풀면 아래와 같은 코드가 됩니다.

for i in 'hello': print(i)
my_iterator = iter('hello') # __iter__ 실행, for 루프에서 실행 i = next(my_iterator) # __next__ 실행 print(i) i = next(my_iterator) print(i) i = next(my_iterator) print(i) i = next(my_iterator) print(i) i = next(my_iterator) print(i) i = next(my_iterator) print(i) # StopIteration 예외 발생, 반복문 탈출

2. __iter__, __next__ 매직 메서드

파이썬에서는 __iter__ 매직 메서드를 사용하여 반복 가능한 객체를 만들 수 있습니다. 이 메서드는 __next__ 메서드를 가진 이터레이터 객체를 반환해야 합니다.

class MyRange:
    def __init__(self, start, end):
        self.start = start
        self.end = end
 
    def __iter__(self):
        return self
 
    def __next__(self):
        if self.start >= self.end:
            raise StopIteration
        value = self.start
        self.start += 1
        return value
 
my_range = MyRange(0, 3)
for i in my_range:
    print(i)
class MyRange:
    def __init__(self, start, end):
        self.start = start
        self.end = end
 
    def __iter__(self):
        return self
 
    def __next__(self):
        if self.start >= self.end:
            raise StopIteration
        value = self.start
        self.start += 1
        return value
 
my_range = MyRange(0, 3)
for i in my_range:
    print(i)

다만 이렇게 순회를 하면 한 번만 순회할 수 있습니다. 이를 해결하기 위해서는 이터레이터를 새로 만들어야 합니다.

3. 이터레이터 재사용

이터레이터를 재사용하고 싶다면 __iter__ 메서드에서 self.current_value 변수를 초기화해야 합니다.

class MyIterator: def __init__(self, stop): self.stop = stop def __iter__(self): self.current_value = 0 # __iter__에서 초기화 return self def __next__(self): if self.current_value >= self.stop: raise StopIteration result = self.current_value self.current_value += 1 return result my_iterator = MyIterator(5) for i in my_iterator: print(i) for i in my_iterator: print(i)

💡 위 코드는 https://pythontutor.com/python-debugger.html#mode=edit 서비스를 통해 시각화해서 단계별로 실행해보면서 이해하시길 권해드립니다.

4. 이터러블과 이터레이터 분리

이 두가지 용어를 혼동하기 쉽지만, 이터러블은 __iter__ 메서드를 가진 객체를 말하고, 이터레이터는 __next__ 메서드를 가진 객체를 말합니다.

우리가 흔히 순회가능한 객체라고 부르는 것은 이터러블 객체입니다. 이 두개를 아래처럼 분리할 수도 있습니다.

class NumberIterator: def __init__(self, start, end): self.current = start self.end = end def __next__(self): if self.current >= self.end: raise StopIteration value = self.current self.current += 1 return value class Numbers: def __init__(self, start, end): self.start = start self.end = end def __iter__(self): return NumberIterator(self.start, self.end) nums = Numbers(1, 4) # 첫 번째 반복 for num in nums: print(f"첫번째: {num}") # 두 번째 반복 (새로운 이터레이터가 생성됨) for num in nums: print(f"두번째: {num}")

5. yield를 사용한 이터레이터

yield 키워드를 사용하면 이터레이터를 간단하게 만들 수 있습니다.

class EvenNumbers: def __init__(self, end): self.end = end def __iter__(self): for i in range(0, self.end, 2): yield i evens = EvenNumbers(7) for num in evens: print(num) # 0, 2, 4, 6
{"packages":["numpy","pandas","matplotlib","lxml"]}
3.5 매직 메서드 - 컬렉션3.7 매직 메서드 - 수치와 산술 연산