본문 바로가기
Computer & Program/python

[python] Iterator(반복자) - 02

by TDRemon 2024. 3. 3.
반응형

안녕하세요. TDR입니다.

저번 시간에 이어서 iterator에 대해서 정리해보겠습니다.

 

[python] Iterator(반복자) - 01

안녕하세요. TDR입니다. 오늘은 python의 Iterator(반복자)에 대해서 간략히 정리해 보겠습니다. Iterator는 python 외에도 왠만한 언어에는 모두 존재하는 개념으로 " 반복 가능한 객체로 "를 뜻합니다.

tdremon.tistory.com

iterator의 특징 중에 하나가 unpacking(언패킹)도 가능하다는 것입니다. 저번 시간에 예제로 썼던 Fruits class를 통해 확인해보겠습니다.

class Fruits:
    fruits_list = ['apple', 'orange', 'banana', 'water melon', 'melon']
    fruits_len = len(fruits_list)

    def __init__(self, count):
        print('init')
        self.count = count

    def __iter__(self):
        print('iter')
        return self
	
    def __next__(self):
        print('next')
        if self.count > 0:
            result = self.fruits_list[self.fruits_len - self.count]
            self.count -= 1
            return result
        else:
            raise StopIteration

a, b, c, d = Fruits(4)
print(a, b, c, d)

## Result ##
init
iter
next
next
next
next
next
orange banana water melon melon

unpacking을 하면 자동으로 개수에 맞게 __next__ 함수가 호출되서 각 값에 할당 되는 것을 알 수 있습니다. 주의할 점은 반환하는 값과 받는 변수의 개수가 동일해야 한다는 점입니다. 많아도 적어도 ValueError를 반환하게 됩니다.

이번에는 iterator에 index를 통해서 접근 하는 방법을 정리해 보겠습니다. index로 접근하기 위해서는 __getitem__함수를 구현해 주면 됩니다. 재밌는 거는 __iter__, __next__를 구현하지 않아도 iterator로서 동작 한다는 것입니다.

class Fruits():
    fruits_list = ['apple', 'orange', 'banana', 'water melon', 'melon']

    def __init__(self, count):
        self.count = count
	
    def __getitem__(self, index):
        if index < len(self.fruits_list):
            return self.fruits_list[index]
        else:
            raise StopIteration
		
print(Fruits(4)[2])
print(Fruits(4)[4])
## Result ##
banana
melon
		
print(dir(Fruits(4)))
## Result ##
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__',
'__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', 'count', 'fruits_list']
		
for i in Fruits(4):
    print(i)
## Result ##
apple
orange
banana
water melon
melon

보시는 바와 같이 Fruits(4)[2]에서 index를 통해서 iterator에서 특정 위치의 값을 가져오는 것을 알 수 있습니다. 그리고 아래 for 문에서는 __iter__, __next__를 구현하지 않았음에도 iterator로서 동작하고 있습니다. 그리고 신기한 것은 dir()을 통해 Fruits(4) 객체가 가지고 있는 함수와 속성 값을 출력해보면 __iter__, __next__가 없습니다. 그래서 명시적으로 호출을 하면 AttributeError가 발생합니다. 그리고 저번 시간에 확인한 unpacking을 해보면 마찬가지로 ValueError가 발생합니다. 그럼에도 for 문이 동작하는 것은 솔직히 저도 왜 동작하는지 이해를 잘 못하고 있습니다...

아무튼 iterator를 직접 제작해서 사용할 수 있고, 필요하다면 index를 통해서 접근할 수 있게도 가능하다는 것을 확인할 수 있었습니다.

반응형

댓글