
"뭐에요? 🤨" 시리즈 1편
평소에 헷갈렸던 것들이나 암기해두면 좋을 것들, 대강 알고 정확한 정의를 몰랐던 것들을 좀 깊게 들어가보면서 질문별, 문제상황별로 포스트를 작성해보겠다. 파이썬에 대해서는 기초적인 문법을 알고 있다고 생각하고 작성한다.
기본적으로 __iter__() 혹은 __getitem__() 스페셜 메서드가 있는 클래스 객체들은 다 이터러블이다. (그 말인즉슨 우리가 만든 커스텀 클래스에 저 스페셜 메서드 하나 이상을 구현해주면 이터러블이 된다는 거다.)
다음과 같은 애들이 파이썬에서 기본적으로 사용할 수 있는 이터러블이다. (for .. in [이_자리에_들어갈_수_있는_애들] 로 생각하면 외우기 쉽다)
list (mutable sequence type)tuple (immutable sequence type)str (immutable, text sequence type)dict (mutable, non-sequence, mapping type)set (mutable, non-sequence type)file iterable 이라고 쓴 자리에 이터러블을 넣어서 사용한다.
for <variable> in <iterable>zip(*iterables, strict=False), map(function, iterable, ...), ... )iter(iterable) → 해당 객체의 이터레이터 리턴. 이 이터레이터는 값들을 쭉 한 번씩 거치는 동안 유효하다.for 문의 경우 루프를 도는 동안 이터레이터를 자동으로 생성해서(자동으로 __iter__()를 호출해준다는 뜻) 이름 없는 변수에 잡아둔다.이터러블 오브젝트의 스페셜 메서드(__iter__())가 호출되면 해당 이터러블에 대한 이터레이터 객체가 생성되고 리턴된다.

이터레이터에는 또 __next__() 라는 스페셜 메서드가 있어서, 이 메서드를 호출하면
따라서 이터레이터 형은 두 개의 메서드를 사용해서 구현된다. (이터러블은 __iter__() 나 __getitem__()이 정의되어 있다면) 이터러블 형은
__iter__()__next__()이 두 개의 메서드를 모두 지원해야 한다. (이터레이터 형에도 __iter__() 메서드가 있다는 것은 이터레이터에 대한 이터레이터도 만들 수 있다는 것이다. 또 이터러블의 조건을 만족하는 것이기도 하므로 이터레이터는 이터러블이다. 따라서 이터러블이 사용되는 곳에 당연히 이터레이터도 쓸 수 있다.)
아래처럼 리스트를 만들고 for 문에 이 리스트(이터러블)을 사용해보자. 그럼 아래와 같은 결과가 나타나는데, 어떻게 돌아가는 걸까?
for 가 하는 일을 풀어서 코드로 써보겠다. for 문이 이터러블을 받으면 이터러블의 __iter__() 를 호출한다. __iter__() 메서드는 이터레이터 객체를 리턴한다. 
for 문의 각 반복마다 내부적으로 __next__() 메서드를 호출하고 이 메서드는 현재 가르키고 있는 인덱스에 해당하는 원소를 반환하고 (이 반환된 값은 i 에 할당된다), 이터레이터 포인터를 다음 원소로 옮긴다. 모든 원소를 다 접근하고 나면 StopIteration exception이 나오고 for 문이 종료된다.
__iter__() 또는 __getitem__() 필요__iter__() 와 __next__() 필요__iter__()) 이터레이터는 이터러블이다.__iter__() 메서드를 자동으로 호출해서 이터레이터를 생성, 리턴하고 루프를 도는 동안 이름 없는 변수에 잡아둔다.__next__()를 호출해서 현재 이터레이터 포인터가 가르키고 있는 곳의 값을 리턴하고, 포인터가 다음 원소를 가르키도록 한다.이터레이터는 이터러블이라고 했다. 이터레이터도 __iter__() 가 있기 때문에 이터러블이 된다.
하지만 중요한 예외가 있는데, 리스트와 같은 컨테이너 객체를 iter() 함수에 전달하거나 for 루프에서 사용할 때마다 새 이터레이터를 만든다. 하지만 이터레이터는 이럴때마다 새 이터레이터를 만들지 않고, 지난 이터레이션에 사용된 이미 소진된 이터레이터를 돌려준다. 차이를 코드로 확인해보자.
리스트에 두 번 for 루프를 돌렸는데 똑같이 처음부터 원소가 잘 나온다. 새로운 이터레이터가 for 문마다 자동으로 생성됐기 때문이다.
id를 확인해봐도 계속 새로운 이터레이터가 생긴 것을 알 수 있다.
이터레이터에 for 문을 적용했더니 두번째 for 문에서는 아무것도 출력되지 않는다. 이미 앞서 만들어진 이터레이터에 대한 이터레이터를 리턴했기 때문이다.
계속 같은 이터레이터이기에 id도 같다.
정리하자면 이터레이터에 대한 이터레이터는 한 번 생긴 것을 계속 쓴다. 하지만 이터레이터가 아닌 이터러블에 대한 이터레이터는 계속 새로 만든다.