파이썬 리액티브하게 짜기 - PyCon Korea 2017

32
파이썬 리액티브하게 짜기 PyCon Korea 2017 한성민

Transcript of 파이썬 리액티브하게 짜기 - PyCon Korea 2017

Page 1: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

파이썬 리액티브하게 짜기 PyCon Korea 2017

한성민

Page 2: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

SPEAKER

편집자

개발팀장

한성민

Page 3: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

INTRODUCTION

리액티브 프로그래밍

RxPy

코루틴 / 제너레이터

CH1.

CH2.

CH3.

Page 4: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

CH1.

리액티브 프로그래밍

Page 5: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

What is reactive programming?

CH 1. 리액티브 프로그래밍

비동기 데이터 흐름에 초점을 맞춘 새로운 패러다임

Page 6: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

어렵잖아

Page 7: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

핵심 키워드 #1

CH 1. 리액티브 프로그래밍

비동기 동기화가 보장되지 않은 데이터를 순차적으로 받아들일 수 있으며

이렇게 받아들인 데이터를 유연하게 처리한다.

Page 8: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

핵심 키워드 #2

CH 1. 리액티브 프로그래밍

반응형 외부에서 어떠한 동작(입력)이 없다면 실행되지 않는다.

Page 9: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

핵심 키워드 #3

CH 1. 리액티브 프로그래밍

경량 데이터 흐름은 각 목적에 맞도록 작게 나눌 수 있으며

작게 나눈 것을 다시 합칠 수 있다. 이를 통해 경량화가 가능하다.

Page 10: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

데이터는 흐릅니다.

CH 1. 리액티브 프로그래밍

Page 11: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

항상 같은 시간에 흐르지는 않습니다. 데이터가 계속 온다고 보장할 수 없습니다.

CH 1. 리액티브 프로그래밍

Page 12: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

이런 서로 다른 시간대의 데이터를 처리하는 것은 결코 쉽지 않습니다.

CH 1. 리액티브 프로그래밍

.next() .subscribe()

Page 13: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

여러 데이터 흐름을 제어해주는 것 리액티브 프로그래밍은 그것을 가능하게 합니다.

CH 1. 리액티브 프로그래밍

서로 다른 시간대에서 병렬(Concurrency)로 오는 데이터들을

순차적으로 (Sequential)

Page 14: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

데이터 흐름만을 봅니다. 따라서 보다 직관적입니다.

CH 1. 리액티브 프로그래밍

Map

Filter

Merge Reduce

(정제) (변환)

(병합) (건너뛰기) (합산)

On Complete

On Error Retry

(재시도)

Skip

(모아두기)

Buffer

Page 15: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

CH2.

RxPy

Page 16: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

ReactiveX (RX)

CH 2. RxPy

Microsoft 2007년 ̀ Volta` 프로젝트 발표

2009년 ̀ Reactive Extensions` 이름으로 공개

2012년 부터 점차적으로 오픈소스로 공개

Page 17: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

def observer_generator(observer): # 옵저버를 통해 “hello” 문자열을 전달합니다. observer.on_next("hello") # 마찬가지로 옵저버를 통해 “world!” 문자열을 전달합니다. observer.on_next("world!") def main(): # 옵저버를 생성하여 미리 정의한 함수에 전달하고 이를 수신할 수 있는 객체를 받습니다. observable = Observable.create(observer_generator) # 옵저버를 수신합니다, 이때에는 on_next로 전달된 변수를 읽어 출력하게 합니다. # 아참! 그리고 아래의 subscribe가 시작되고나서 위쪽의 observer_generator가 실행됩니다. observable.subscribe(on_next=lambda value: print(value))

hello_world.py

observable.create (옵저버 생성)

observer_generator

observer

Page 18: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

def observer_generator(observer): # 옵저버를 통해 “hello” 문자열을 전달합니다. observer.on_next("hello") # 마찬가지로 옵저버를 통해 “world!” 문자열을 전달합니다. observer.on_next("world!") def main(): # 옵저버를 생성하여 미리 정의한 함수에 전달하고 이를 수신할 수 있는 객체를 받습니다. observable = Observable.create(observer_generator) # 옵저버를 수신합니다, 이때에는 on_next로 전달된 변수를 읽어 출력하게 합니다. # 아참! 그리고 아래의 subscribe가 시작되고나서 위쪽의 observer_generator가 실행됩니다. observable.subscribe(on_next=lambda value: print(value))

hello_world.py

observable

1. next(‘hello’)

2. next(‘world!’)

observer

1. print(‘hello’)

2. print(‘world!’)

on_next를 통해 데이터 전달

on_next로 들어온 데이터 출력

Page 19: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

from rx import Observable, Observer class PrintObserver(Observer): def on_next(self, value): print('on_next value:%s’ % (value)) def on_completed(self): print('on_completed !') def on_error(self, value): print('on_error value:%s’ % (value)) def observer_generator(observer): observer.on_next(“break") observer.on_next(“the ice!") while True: message = input() if message: observer.on_next(message) else: observer.on_completed() break def main(): observable = Observable.create(observer_generator) observable.subscribe(PrintObserver())

ice_breaking.py

Observable (데이터 전달자)

Observable (데이터 수신자)

subscribe()

next(‘break’)

next(‘the ice!’)

next(‘message’)

print()

print()

print()

on_next

on_next

on_next

completed()

on_completed print()

1. subscribe에 미리 정의한 객체를 이용해서 수신 메시지를 확장하실 수 있습니다.

Page 20: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

CH3.

코루틴 / 제너레이터

Page 21: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

코루틴 (Coroutine)?

CH 3. 코루틴 / 제너레이터

일반적으로 함수와 달리 함수를 호출한 부모와 호출된 함수가

“동등한 관계”에 있는 루틴

파이썬 한정: 코루틴은 입력받아 처리하는 루틴

Page 22: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

코루틴과 일반함수 비교

CH 3. 코루틴 / 제너레이터

일반함수

함수호출 (Call)

결과반환 (Return)

Parameters

Result

코루틴 함수

함수호출 (Call)

Parameters

Yield

Yield

Yield

메인코드 메인코드

호출자 연산

호출자 연산

호출자 연산

Send

Send

Send

Page 23: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

Use Case

CH 3. 코루틴 / 제너레이터

Init Data

호출자 코루틴

2. yield를 통해 호출자의 입력을 기다림 (호출자 코드로 돌아감)

1. 코루틴에 적용할 초기 데이터 삽입

3. 호출자에게 입력을 받았다면 코루틴 코드로 돌아와서 로직 실행.

로직중 yield가 나타나면 다시 부모 코드로 돌아감 (반복)

next()

Yield

Yield

4. 마지막으로 호출자에서 코루틴을 종료시킴. Close

Page 24: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

제너레이터 (Generator)?

CH 3. 코루틴 / 제너레이터

코루틴이 대식가라면 제너레이터는 아낌없이 주는 나무

yield를 통해 데이터 생성하는 생성체

Page 25: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

range 함수를 아세요?

CH 3. 코루틴 / 제너레이터

def main(): # range 함수를 이용하여 # value에 0부터 2까지 각각의 값을 삽입하며 3번 반복합니다. for value in range(3): print(u’current value %d' % (value)) OUTPUT: current_value 0 current_value 1 current_value 2

Page 26: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

range 함수 제너레이터로 구현하기

CH 3. 코루틴 / 제너레이터

# 제너레이터로 만들어진 range 함수입니다! def custom_range(number): index = 0 while(index < number): # 우리는 이때 이 함수를 호출한 부모로 돌아가 값을 전달하고, # 이 함수를 다시 호출하기 전까지 부모의 로직을 진행합니다. # 이것이 제너레이터의 핵심입니다. 기억하세요! yield index index += 1

Page 27: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

coroutine_generator.py

def main(): # 기존의 range 함수를 사용해봅시다. for value in range(3): print(u'original range %d' % (value)) # 구분을 위해 한칸을 띄워줍시다. print(u'\n') # 우리가 방금전에 만든 함수를 사용해봅시다. for value in custom_range(3): print(u'custom range %d' % (value))

OUTPUT original range 0 original range 1 original range 2 custom range 0 custom range 1 custom range 2

Page 28: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

Use Case

CH 3. 코루틴 / 제너레이터

Large Data

Memory

Process

yield

1. 실시간으로 읽어들이는 커서에서 데이터셋이 500개가 쌓일 때마다

yield return

2. 실제로 메모리에는 500개 데이터뿐이니 메모리 부족 문제는 없음

3. 500개의 데이터를 가공하고 Process가 끝나면

500개 데이터를 메모리에서 비움 마찬가지로 메모리 부족 문제 없음

4. Process가 끝나면 다시 Large Data에서 500개의

데이터를 가져옴.

Page 29: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

제너레이터 결론

CH 3. 코루틴 / 제너레이터

실시간으로 들어오는 데이터는 제너레이터를 사용하면

메모리를 안정적으로 운영 가능! (성능이 크게 차이나지 않음)

Page 30: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

코루틴과 제너레이터 차이가 뭐에요?

CH 3. 코루틴 / 제너레이터

코루틴 함수

함수호출 (Call)

Parameters

Yield

Yield

Yield

메인코드

호출자 연산

호출자 연산

호출자 연산

Send

Send

제너레이터

함수호출 (Call)

Parameters

Yield

Yield

Yield

메인코드

호출자 연산

호출자 연산

호출자 연산

Return

Return

Return

Send

Page 31: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

Question

Page 32: 파이썬 리액티브하게 짜기 - PyCon Korea 2017

수고하셨습니다.

[email protected] http://github.com/KennethanCeyer/pycon-kr-2017

Email GitHub