小学社会308779 views
小学算数1195619 views
高校生物550029 views
小学理科717511 views
数学講師2856982 views
中学社会667260 views
高校化学2914333 views
MathPython492158 views
高校物理158399 views
高校倫理1434006 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 を活用すると、コルーチンを協調的なタスクとして柔軟に制御できます。