python の yield。サクッと理解するには return と比較

yield がどうもピンとこない

python の yield は非常に便利ですが、イマイチ判りにくかったりします。内部的な仕組み、たとえば iter とか next を理解しとけばいいのですが、それはそれで面倒です。

そこで内部の仕組みはひとまず横において、とりあえず yield の動きを理解することを目指します。そして、そういう目的なら return と比較するのが簡単です。

- 目次 -

スポンサーリンク

return との比較

returnyeild を比較してみます。

まず return ですが、戻り値のある return の動作は

  • 関数の処理を 終了
  • 値を返す

です。

一方、yeild

  • 関数の処理を 一旦停止
  • 値を返す

という動きをします。
一旦停止なので、yeild の処理は再開されます。

図にすると

ret_func
ret_func

yeild の場所で一旦停止し、再開時は次の行からスタートします(再開のきっかけは後述)。

なんのために ?

でわ、yield があると何が便利なのでしょうか。

単純な例ですが、たとえば 1GB の巨大なテキストファイルがあるとします。そして、この巨大なファイルを読み込み、データを渡してくれる関数を作るとします。

これを普通にやろうとすると、受け渡し用のメモリが 1GB という巨大なサイズになってしまいます。

ところが yield を使えば、少量、たとえば 1 行づつデータを読み込み、その都度 yield すればいいので、メモリの使用量はほんの僅かで済んでしまいます。

yield return

使ってみる

ループで

yield がなくなるまで for 文が回りつづけます。
for 文の裏側で 「処理(yield まで) ⇒ 一旦停止 ⇒ 再開(yield まで) ⇒ 一旦停止」 が繰り返され、その都度、yield の返す値が x に代入されます。

ループ以外で

for 文のような繰り返し処理を使わない場合は、内部の仕組みを自分で意識する必要があります。

yield を含む関数を呼び出すと generator(ジェネレータ)というものが返ってきます。そのジェネレータの next() を呼ぶと、yield までの処理を実行し、値を返してくれます。next() をもう一度呼ぶと、yield の次の行から再開され、次の yield まで処理を実行し、値を返してくれます。
yield の個数以上に next() を呼ぶと StopIteration 例外が raise されます。

スポンサーリンク

コメントはお気軽に