[Python >= 3.9] 同期ジェネレータ

・処理結果をまとめてListで返却するのが何かと都合が悪い場合に使う。
 ・件数が多すぎて消費メモリが重い
 ・処理後のデータを保持しておく必要性がない
・再帰呼出しでコールスタックを軽減したい場合に使う。

■1件ずつ処理して呼び出し元に一時的に戻る
# typing.Generator は3.9から非推奨
from collections.abc import Generator

def my_generator(num: int) -> Generator[int, None, None]:
    print("    my_generator START")

    for n in range(num):
        print(f"    my_generator [{n}]")
        yield n

    print("    my_generator END  ")

for item in my_generator(3):
    print(f"for [{item}]")


■実行結果
    my_generator START
    my_generator [0]
for [0]
    my_generator [1]
for [1]
    my_generator [2]
for [2]
    my_generator END
■1件ずつ処理して呼び出し元に一時的に戻る (呼び出し元から値を渡す)
# typing.Generator は3.9から非推奨
from collections.abc import Generator

def my_generator(num: int) -> Generator[int, int, None]:
    print("    my_generator START")

    for n in range(num):
        print(f"    my_generator [{n}]")
        recv = yield n
        print(f"    recv[{recv}]")

    print("    my_generator END  ")

print("new Generator")
gen = my_generator(3)
value: int | None = None    # '|'の記述は>= 3.10
print("while START")
while True:
    try:
        if value is None:
            value = next(gen)
        else:
            value = gen.send(value + 10)

        print(f"while [{value}]")

    except StopIteration:
        print("while StopIteration")
        break

    print("while LOOP")

print("while ND")


■実行結果
new Generator
while START
    my_generator START
    my_generator [0]
while [0]
while LOOP
    recv[10]
    my_generator [1]
while [1]
while LOOP
    recv[11]
    my_generator [2]
while [2]
while LOOP
    recv[12]
    my_generator END
while StopIteration
while ND