中学理科1625756 views
MathPython489968 views
小学社会308525 views
ヒストリア282760 views
中学英語808125 views
雑学1472443 views
小学算数1193669 views
数学講師2847003 views
中学社会666920 views
高校化学2912417 views
Help
Tools

English

Python コルーチンの内部実装(send, throw, close)

コルーチンは send, throw, close メソッドで外部から制御できます。これらを使うと、双方向通信やエラーハンドリングが可能になります。

send:値を送り込む

yield 式は値を受け取れます。send で値を渡すと、yield 式の評価結果になります。

def accumulator():
    total = 0
    while True:
        value = yield total
        if value is None:
            break
        total += value

coro = accumulator()
next(coro)            # ジェネレータを起動(最初の yield まで進む)
print(coro.send(10))  # 10
print(coro.send(20))  # 30
print(coro.send(5))   # 35

最初の next() は send(None) と同等で、ジェネレータを最初の yield まで進めます。

throw:例外を投入する

throw でコルーチン内部に例外を発生させられます。

def coro_with_error_handling():
    try:
        while True:
            value = yield
            print(f"Received: {value}")
    except ValueError as e:
        print(f"Error handled: {e}")
        yield "recovered"

c = coro_with_error_handling()
next(c)
c.send(1)                          # Received: 1
result = c.throw(ValueError, "something wrong")
print(result)                      # recovered

close:コルーチンを終了する

close は GeneratorExit を投入してコルーチンを終了させます。

def resource_manager():
    print("Acquiring resource")
    try:
        while True:
            yield
    finally:
        print("Releasing resource")

c = resource_manager()
next(c)      # Acquiring resource
c.close()    # Releasing resource

finally ブロックでクリーンアップ処理が実行されます。

状態マシンの実装例

def state_machine():
    state = "IDLE"
    while True:
        event = yield state
        if state == "IDLE" and event == "start":
            state = "RUNNING"
        elif state == "RUNNING" and event == "stop":
            state = "IDLE"

sm = state_machine()
print(next(sm))         # IDLE
print(sm.send("start")) # RUNNING
print(sm.send("stop"))  # IDLE

send, throw, close を活用すると、コルーチンを協調的なタスクとして柔軟に制御できます。