Python3 – yield文によるジェネレーターの実装

return文の確認

yield文はreturn文と同様に関数の中で使われ、戻り値を指定するが、その挙動は全く異なる。

まず準備として、通常のreturn文を持つ関数の動作を確認。呼び出されるたびに常に関数の先頭からreturn文まで実行される。

yield文にするとジェネレーターが生成される

このreturn文をyield文に変更してみると、関数の戻り値を返すのではなく、この関数がジェネレーターオブジェクトのコンストラクターとなっている。

ジェネレーターオブジェクトには、(Python3では)__next__()メソッドがあって、ジェネレーターで生成された値を順次取り出してくれる。そこで上のfunc1()でジェネレーターのインスタンスを生成し、直接値を取り出してみる。

このジェネレーターは値を1つしか生成しないので、2つ目を取り出そうとするとStopIteration例外を投げる。

yield文によるジェネレーターの挙動

以下の例は、3つの値を返すジェネレーターの例で、確認のためにyield文の前の処理をprint文で表示させるようにしている。なお、ここでは__next__()メソッドの代わりに組み込み関数next()を用いている。

関数で生成されるのはジェネレーターでStopIterationを投げるので、次のようにfor文で使える。

yiled文とreturn文を混ぜた場合

関数の中でyield文を書くと、return文があってもジェネレーターが生成される。

ただしreturn文があるとそこでStopIterationが投げられる。このとき、return文で指定した戻り値が得られるようだが、ジェネレーターとしては無視されるらしい。

このジェネレーターをfor文で使うと、以下のようにreturn文の手前まで実行される。

実装の例

たとえば引数を与えて、その数以下であるフィボナッチ数列を返すジェネレーターを考える。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です