서브루틴
- 메인루틴에서 서브루틴을 호출하면 서브루틴의 코드를 실행한뒤, 다시 메인 루틴으로 돌아옴.
- 서브루틴이 끝나면 서브루틴의 내용은 모두 사라짐.
- 서브루틴은 메인루틴에 종속된 관계임.
def add(a,b): #서브 루틴
c = a + b
print(c)
print('add 함수')
def calc(): #메인 루틴
add(1,2)
print('calc 함수')
calc()
>>> 3
>>> add 함수
>>> calc 함수
코루틴 (cooperative routine)
- 코루틴은 함수가 종료되지 않은 상태에서 메인루틴의 코드를 실행한 뒤, 다시 돌아와서 코루틴의 코드를 실행함.
- 코루틴은 코드를 여러 번 실행할 수 있음.
- 코루틴은 진입점(함수의 코드를 실행하는 지점)이 여러개임.
- 코루틴은 제너레이터의 특별한 형태임.
- 코루틴은 실행 상태를 유지하기 위해 while True를 사용해서 무한루프로 동작함.
- 코루틴에 값을 보내면서 코드를 실행할 때는 send 메서드를 사용함.
- send 메서드가 보낸 값을 받아올 때는 (yield) 형식으로 변수에 저장함.
변수 = (yield)
next (코루틴객체)
코루틴객체.send(값)
def number_coroutine():
while True:
x = (yield) #코루틴 바깥에서 값을 받아옴.
print(x)
co = number_coroutine()
next(co) #코루틴 안의 yield까지 코드 실행
co.send(1) #코루틴에 숫자1을 보냄.
co.send(2) #코루틴에 숫자2을 보냄.
co.send(3) #코루틴에 숫자3을 보냄.
코루틴 바깥으로 값 전달하기
- (yield 변수) 형식으로 값을 받아오면서 바깥으로 값을 전달함.
def sum_coroutine():
total = 0
while True:
x = (yield total) #코루틴 바깥에서 값을 받아오면서 바깥으로 값을 전달함.
total += x
co = sum_coroutine()
print(next(co))
print(co.send(1))
print(co.send(2))
print(co.send(3))
>>> 0
>>> 1
>>> 3
>>> 6
* next: 값을 보내지 않으면서 코루틴의 코드를 실행할 때
* send: 값을 보내면서 코루틴의 코드를 실행할 때
* 제너레이터: next함수를 반복 호출하여 값을 얻어내는 방식
* 코루틴: next함수를 한번만 호출한 뒤 send로 값을 주고 받는 방식
코루틴 강제종료하기
- 코루틴객체.close()를 사용함.
def number_coroutine():
while True:
x= (yield)
print(x, end ='')
co = number_coroutine()
next(co)
for i in range(20):
co.send(i)
co.close()
GeneratorExit 예외 처리하기
- 코루틴 객체에서 close 메서드를 호출하면 코루틴이 종료될 때 GeneratorExit 예외가 발생함.
def number_coroutine():
try:
while True:
x = (yield)
print(x, end ='')
except GeneratorExit:
print()
print('코루틴 종료')
co = number_coroutine()
next(co)
for i in range(20):
co.send(i)
co.close()
코루틴 안에서 예외 발생시키기
- 코루틴객체.throw(예외명, 에러메시지)
- 지정한 에러메시지는 except as의 변수에 들어감.
def sum_coroutine():
try:
total = 0
while True:
x=(yield)
total += x
except RuntimeError as e:
print(e)
yield total
co = sum_coroutine()
next(co)
for i in range(20):
co.send(i)
print(co.throw(RuntimeError, '예외로 코루틴 끝내기'))
하위 코루틴의 반환값 가져오기
- 변수 = yield from 코루틴()
- 해당 코루틴에서 return으로 반환한 값을 가져옴.
- 코루틴 바깥에서 send로 하위 코루틴까지 값을 보낼 수 있음.
def accumulate():
total = 0
while True:
x = (yield)
if x is None:
return total
total += x
def sum_coroutine():
while True:
total = yield from accumulate()
print(total)
co = sum_coroutine()
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)
>>> 55
>>> 5050
__name__
시작점에서 import로 모듈을 가져오고 실행했을때는 모듈의 __name__에 모듈명이 들어감.
시잠점에서 __name__을 직접 실행했을때는 __main__이 들어감.
if__name__=='__main':
현재 스크립트 파일이 프로그램의 시작점(entry point)이 맞는지 판단하는 작업임.
스크립트 파일이 메인 프로그램으로 사용될 때와 모듈로 사용될 때를 구분하기 위함.
# hello.py 파일
print('hello 모듈 시작')
print('hello.py__name__:', __name__)
print('hello 모듈 끝')
>>> hello 모듈 시작
>>> hello.py__name__: __main__
>>> hello 모듈 끝
# main.py 파일
import hello
>>> hello 모듈 시작
>>> hello.py__name__: hello
>>> hello 모듈 끝
-------------------------------------
# calc.py 파일
def add(a,b):
return a+b
def mul(a, b):
return a*b
if __name__ == '__main__':
print(add(10,20))
print(mul(10,20))
>>> 30
>>> 200
--------------------------------------
# main.py 파일
import calc
>>>