본문 바로가기

Python/Intermediate

[Python] 병행성(Concurrency)(1) - basic

  • iterable 객체 - 반복 가능한 객체
  • iterator 객체 - 값을 차례대로 꺼낼 수 있는 객체

 

iterable 객체 

 

# 반복 가능한 이유? -> 내부적으로 iter() 함수 호출
t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

# for 반복
for c in t:
    print(c, end=' ')
    
--------------------------------------------[result]

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 

 

 

iterator 객체

 

a=t.__iter__()
print([next(a) for _ in range(len(t))])
# ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

# while 반복
w = iter(t)
while True:
    try:
        print(next(w), end=',')
    except StopIteration:
        break
# A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,

 

 

반복적 객체 확인

 

from collections import abc

# 반복형 확인, dir, hasattr, abc.Iterable 상속확인
print(dir(t))
print(hasattr(t, '__iter__'))
print(isinstance(t, abc.Iterable))
# ['..., '__iter__', ...]
# True
# True

print(type(t))
# < class 'str' >

 

 

Generator 미사용 샘플 코드 - 이터레이터 클래스(iterator class), next 로 구현

 

# next 패턴
class WordSplitter:
    def __init__(self, text):
        self._idx = 0
        self._text = text.split(' ')

    def __next__(self):
        # print('Called __next__')
        try:
            word = self._text[self._idx]
        except IndexError:
            raise StopIteration('Stopped Iteration.')
        self._idx += 1
        return word

    def __repr__(self):
        return 'WordSplit(%s)' % (self._text)


wi = WordSplitter('Do today what you could do tomorrow')

print(wi)
# WordSplit(['Do', 'today', 'what', 'you', 'could', 'do', 'tomorrow'])
print(next(wi))
print(next(wi))
print(next(wi))
print(next(wi))
print(next(wi))
print(next(wi))
# Do
# today
# what
# you
# could
# do
# tomorrow
print(next(wi)) # 오류 발생
# print(next(wi)) # StopIteration: Stopped Iteration.

 

 

이 클래스는 __iter__() 메서드가 없기 때문에,
다음처럼 for ... in 구문에서 사용할 수 없습니다:

 

for w in WordSplitter("형님 최고입니다"):
    print(w)
#     for w in WordSplitter("형님 최고입니다"):
# TypeError: 'WordSplitter' object is not iterable

 

 

Generator 사용 샘플 코드

 

# Comprehension 패턴 (https://wikidocs.net/22805)
# Generator 패턴 (https://wikidocs.net/16069)
# 1.지능형 리스트, 딕셔너리, 집합 -> 데이터 양 증가 후 메모리 사용량 증가 -> 제네레이터 사용 권장
# 2.단위 실행 가능한 코루틴(Coroutine) 구현과 연동
# 3.작은 메모리 조각 사용

class WordSplitGenerator:
    def __init__(self, text):
        self._text = text.split(' ')
    
    def __iter__(self):
        # print('Called __iter__')
        for word in self._text:
           yield word # 제네레이터
        return
    
    def __repr__(self):
        return 'WordSplit(%s)' % (self._text)

wg = WordSplitGenerator('Do today what you could do tomorrow')

wt = iter(wg)

print(wt)
print(wg)
# <generator object WordSplitGenerator.__iter__ at 0x7f87080740b0>
# WordSplit(['Do', 'today', 'what', 'you', 'could', 'do', 'tomorrow'])
print(next(wt))
print(next(wt))
print(next(wt))
print(next(wt))
print(next(wt))
print(next(wt))
print(next(wt))
# Do
# today
# what
# you
# could
# do
# tomorrow
# # print(next(wt)) # error
# StopIteration


# for ... in 구문에서 사용 가능:
for w in WordSplitGenerator("형님 최고입니다"):
    print(w)
# 형님
# 최고입니다