0. Introduction
- 병행성을 위한 방법으로 generator와 coroutine을 알아보고자 한다.
- 이번 포스팅에서는 __iter__와 __next__ 을, 다음 포스팅에서는
generator
를 알아본다. - 첫 번째로 병행성이 무엇을 의미하는 건지, 이와 유사한 개념으로 병렬성은 무엇인지 학습한다.
- 두 번째로, Generator를 이해하기 위해서 __iter__와 __next__ 을 먼저 학습한다.
1. 병행성과 병렬성이란??
- 동시성, 병행성(Concurrency): 하나의 core에서 하나 이상의 process(또는 thread)가 여러 실행 단위를 번갈아 실행하면서, 동시 진행되는 것처럼 보이는 것
- 병렬성(parallelism): 물리적으로 둘 이상의 코어를 실행해서 하나 이상의 prcess가 한 꺼번에 진행되는 것- > 속도 향상 목적
- 병행성 은 단일 프로그램 안에서 여러 일을 쉽게 해결하기 위해 사용된다.
- thread는 하나지만, 마치 동시에 일을 하고 있는 것처럼 수행한다.
- 예) 공부하다가 강의 멈춰놓고, 밥 먹고 와서 강의를 중단한 부분부터 다시 시작하는 것
- 파이썬에서는 병행성 과 병렬성 을 모두 지원한다.
- 그리고, 파이썬 실력을 결정하는 중요한 내용이다.
2. __iter__와 __next__
2.1 __iter__와 __next__ 용어 정리
- __iter__
- __iter__: iter() built-in function이 호출하는 메소드
- iter(): 호출된 __iter__의 return 값인 iterator를 반환한다.
- __next__
- __next__: next() built-in function이 호출하는 메소드
- iter 가 있는 용어들에 대해 정리하면서 알아보자.
iteration이란?
- The process of looping through the objects or items in a collection
번역하자면 하나의 여러 값들이 담겨진 목록에서 객체들 또는 값들을 ‘순회’하는 과정
그러면 파이썬에서 iteration 상황은 무엇이 있을까??
Definite iteration 상황: 미리 반복 횟수를 명백하게 정한 상황. ex) for 문
Indefinite iteration 상황: 몇 가지 조건이 만족될 때까지 code block을 실행하는 상황. ex) while 문
iteration이란 게 뭔지 알았으니, __iter__
를 사용하는 ‘iterable’ 과 ‘iterator’의 차이에 대해 알아보자.
iterable
- An object(or the adjective used to describe an object) that can be iterated over
dir()
로 확인했을 때,__iter__
또는__getitem__
을 가지고 있는 객체
iterator: Type의 한 종류
iter()
:__iter__
method를 호출하여 이 method의 값을 반환하는 함수- The built-in function used to obtain an iterator from an iterable
즉, iterator의 의미는
- The object that produces successive items or values from its associated iterable
- iterable object로부터 연속적인 값을 낳는(yield) 값 생성기로 ‘반복자’라고 한다.
iter()
이 반환하는 객체의 typenext()
function의 기준으로 보자면,__next__
을 가지고 있는 객체로서 최종적으로 iterator가 갖고 있는 매직메서드는__iter__
와__next__
라고 볼 수 있다.
- The object that produces successive items or values from its associated iterable
2.2 Iterator 관련 data type
iterator를 반환하는 data type들:
- for, collections, string, list, dict, set, tuple, unpacking, *args
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# string > iter('foobar') <str_iterator object at 0x036E2750> # list > iter(['foo', 'bar', 'baz']) <list_iterator object at 0x036E27D0> # tuple > iter(('foo', 'bar', 'baz')) <tuple_iterator object at 0x036E27F0> # set > iter({'foo', 'bar', 'baz'}) <set_iterator object at 0x036DEA08> # dict > iter({'foo': 1, 'bar': 2, 'baz': 3}) <dict_keyiterator object at 0x036DD990>
iterator를 반환하지 않는 data type들
- Integer, foat, built-in functions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# Integer >> iter(42) Traceback (most recent call last): File "<pyshell#26>", line 1, in <module> iter(42) TypeError: 'int' object is not iterable # Float >>> iter(3.1) Traceback (most recent call last): File "<pyshell#27>", line 1, in <module> iter(3.1) TypeError: 'float' object is not iterable # Built-in functions >>> iter(len) Traceback (most recent call last): File "<pyshell#28>", line 1, in <module> iter(len) TypeError: 'builtin_function_or_method' object is not iterable
2.3 iter() 과 next() 예제
내장함수
next()
는 값 생성기 iterator으로부터 다음 값을 얻기 위해 사용된다.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# a는 iterable list다. > a = ['foo', 'bar', 'baz'] # iter을 통해서 a의 iterator를 만든다. > itr = iter(a) > itr <list_iterator object at 0x031EFD10> # nest()를 통해서 itr 안의 다음 값을 얻는다. > next(itr) 'foo' > next(itr) 'bar' > next(itr) 'baz' # 값이 다 소진되면 다음과 같은 Error를 띄운다. > next(itr) StopIteration
만약 iterator로 전환하지 않고, 그냥 사용한다면???
iterator가 아니므로
next()
를 사용할 수 없다.즉
__iter__
을 호출하여 전환해야 사용이 가능하다.1 2 3 4 5 6 7 8
> w = [1,2,3,4,5] # iter()로 iterator로 전환하지 않았기 때문에 __next__가 없다. > print(dir(w)) ['__add__', '__class__', '__iter__', ..... 'sort'] > print(next(w)) TypeError: 'list' object is not an iterator
2.4 iter() 과 next() 토대로 for문 이해하기
그러면
__iter__
과__next__
를 토대로 for 문을 이해해보자.1 2 3 4 5 6 7 8 9
> t = 'ABCDEF' > for c in t: > print(c) A B C D E F
어떻게 해서 하나씩 출력되는 것일까???
for문의 구조를 다시 확인해보자
1 2
> for <var> in <iterable>: > <statement(s)>
in 다음에는 iterable이 온다. 그러면 어떻게 하나씩 반환될까??
__iter__
과__next__
와 연결시켜보자.iterable을 입력하면 for문에서
iter()
을 호출하여 iterable객체를iterator
로 바꾼 후,__next__
method를 통해 하나씩 출력된는 원리라는 걸 이해할 수 있다.하지만 iterator를 입력해도 for문에서 알아서
__next__
method를 통해 하나씩 출력한다.
위에 for문을 while문으로 만들어서 구체적으로 이해해보자.
|
|
2.5 __iter__ 확인하는 방법
|
|
2.6 class로 __next__ 구현하기
|
|
- 구현했지만, 코드량이 많아진다. 그러면 제네레이터를 사용해서 구현해보자.
|
|