kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

ジェネレータ(続き2)

一応わかった気になったけど
どこで止まるかをしっかりイメージできないと応用が効かない気がする
さらに細かく書いてみた

def gen():
    print("before yield")
    y = yield 1.0
    print("yield 1.0 returned", y)
    y = yield 2.0
    print("yield 2.0 returned", y)
    y = yield 3.0
    print("yield 3.0 returned", y)
    return "returning"

g = gen()
print("calling next")
r = next(g)
print("next returned", r)
r = g.send(1)
print("g.send(1) returned", r)
r = g.send(2)
print("g.send(2) returned", r)
r = g.send(3)
print("g.send(3) returned", r)

実行結果

calling next
before yield
next returned 1.0
yield 1.0 returned 1
g.send(1) returned 2.0
yield 2.0 returned 2
g.send(2) returned 3.0
yield 3.0 returned 3
Traceback (most recent call last):
  File "/Users/takahiro/study/PCAD/practice.py", line 23, in <module>
    r = g.send(3)
StopIteration: returning

絵にしてみる
うまく表現できるかな

f:id:kb84tkhr:20190318210653j:plain

こんな感じか
だいぶイメージはできた

ところでこれってコルーチンじゃねーのみたいな気がするけど
Pythonでコルーチンと呼ばれるものは(似てるけど)別物らしい
なんだろう
しかしこのへんにしておく

さてやたら回り道したけど型
上の説明に従えばこうなるはず

def gen() -> Generator[float, int, str]:
    y = yield 1.0
    y = yield 2.0
    y = yield 3.0
    return "returning"

g = gen()
r = next(g)
r = g.send(1)
r = g.send(2)
r = g.send(3)

通るかな

$ mypy --strict practice.py
$

通った