본문 바로가기
Python

[Python] coroutine (코루틴)

by UnoCode 2020. 6. 29.

코루틴은 동시성! 이라고 한마디로 정의하겠습니다.

 

코루틴과 비슷한 개념은 함수입니다.

함수에는 return이 있죠.

 

코루틴에는 제너레이터에서 보았던 Yield가 있습니다.

 

그럼 동시성이라는 개념은 무엇일까요??

 

코드로 보시죠

 

import time


def coroutine_test():
    greeting = "good "
    while True:
        text = (yield greeting)
        print("text = ", end=""), print(text)
        greeting += text


if __name__ == "__main__":
    cr = coroutine_test()
    print("cr=", end=""), print(cr)

    next(cr)
    time.sleep(2)

    print("send 1")
    print(cr.send("morning"))
    time.sleep(2)

    print("send 2")
    print(cr.send("afternoon"))
    time.sleep(2)

    print("send 3")
    print(cr.send("evening"))
    time.sleep(2)

실행 결과보고 감이 오시나요?

 

함수를 호출할때 마다 그값이 저장 되어 출력되고 있는 모습을 볼수 있습니다.

 

동시성은 보통  UNITY에 많이 사용합니다.  게임만드는 것으로 유명한데요

 

쉽게 생각해서 "인벤토리" 라고 보시면 됩니다.

 

 

코루틴의 특징

 

1. 파이썬에는 yield 문이라는 특수한 구문이 있습니다. return 처럼 동작하지만, 사실은 입력으로 동작합니다

    (이유는 메인루틴에 구혜를 받지 않기 때문이죠)

 

2. next(코루틴)은 코루틴 함수의 첫번쨰 yield 까지 호출한다음 대기합니다. 

  두번째 next(코루틴 함수)를 호출하면 iteration이 가능한 곳까지 next함수가 수행된 뒤에는 StopIteration을 호출하는

  거죠

 

3. 만약 yield 문이 특정 변수에 할당된다면, 만들어진 코루틴 객체에서 "코루틴함수.send(value)" 형식으로 호출

   합니다. 만약 변수에 값이 할당되어야 하는데 아무런 값이 들어오지 않는 경우는 에러를 발생시킵니다.

 

import time


def coroutine_test():
    greeting = "good "
    while True:
        text = (yield greeting)
        print("text = ", end=""), print(text)
        greeting += text


def coroution_test(num):
    greeting = num
    while range(3):
        print(f"Number : {(yield greeting)}")


if __name__ == "__main__":
    cr = coroutine_test()
    print("cr=", end=""), print(cr)

    next(cr)
    time.sleep(2)

    print("send 1")
    print(cr.send())
    time.sleep(2)

 

제너레이터와 코루틴의 차이점

 

  • 제너레이터는 next를 반복 호출하여 값을 얻어내는 방식
  • 코루틴은 next함수를 한번 호출한 되 send값을 주고 받는 형식

 

코루틴을 종료하고 예외 처리하기

 

def sum_corutione():
    try:
        total = 0
        while True:
            x = (yield)
            total += x

    except RuntimeError as e:
        print(e)
        yield total  # 코루틴 밖으로 값 전달


co = sum_corutione()
next(co)

for i in range(20):
    co.send(i)

print(co.throw(RuntimeError, "예외 처리 코루틴 끝"))  # 190
# except에서 값전달

코루틴은 이렇게 값도 가져올 수 있습니다. ^^ 신기 방기

 

하위 코루틴의 반환값 가져오기

다음은 코루틴에서 숫자를 누적한 뒤 합계를 yield from으로 가져옴

def accumulate():
    total = 0
    while True:
        x = (yield)
        if x is None:
            return total
        total += x


def sum_co():
    while True:
        total = yield from accumulate()
        print(total)


co = sum_co()
next(co)

for i in range(1, 11):
    co.send(i)

co.send(None)

for i in range(1, 101):
    co.send(i)

co.send(None)

 

응용 문제 풀기

 

처음에 배웠던 코드중 

 

import time


def coroutine_test():
    greeting = "good "
    while True:
        text = (yield greeting)
        print("text = ", end=""), print(text)
        greeting += text


if __name__ == "__main__":
    cr = coroutine_test()
    print("cr=", end=""), print(cr)

    next(cr)
    time.sleep(2)

    print("send 1")
    print(cr.send("morning"))
    time.sleep(2)

    print("send 2")
    print(cr.send("afternoon"))
    time.sleep(2)

    print("send 3")
    print(cr.send("evening"))
    time.sleep(2)

 

출력 값이 이렇게 나왔습니다.

 

아래의 결과 값을 같도록 해보세요.

 

 

import time


def coroutine_test():
    greeting = "good "
    while True:
        text = (yield greeting)
        print("text = ", end=""), print(text)
        greeting = "good " + text


if __name__ == "__main__":
    cr = coroutine_test()
    print("cr=", end=""), print(cr)

    next(cr)

    print("send 1")
    print(cr.send("morning"))

    print("send 2")
    print(cr.send("afternoon"))

    print("send 3")
    print(cr.send("evening"))


 

저는 하나씩 종이에 적어가면서 해보니 text를 출력한 직후 greeting에 text값을 더해 주면 되었습니다.

 

여려분은 어떻게 해결 했나요

 

뎃글로 다른 방법은 어떤게 있는지 공유해주세요

'Python' 카테고리의 다른 글

[Python] 크롤링-billboard 차트 - csv  (0) 2020.07.02
[Python] asyncio  (0) 2020.07.02
[Python] Multiprocessing  (2) 2020.06.29
[Python] Thread  (0) 2020.06.29
[Python] Lambda 실습  (0) 2020.06.28

댓글