前回紹介したyield式には、もう一つの形式がある。それがyield from式だ。これは「yield from 式」のような形で記述する。このとき「式」を評価した結果は反復可能オブジェクトまたはイテレータである必要がある。それが反復可能オブジェクトであれば、yield from式ではそれからイテレータを取り出して、そのイテレータから値を呼び出し側に順次返送できる機能だ。yield from式で使用するイテレータのことを「サブジェネレータ」と、yield from式で他のイテレータを利用することを「サブジェネレータへの委譲」呼ぶこともある。
簡単な例を以下に示す。
def sample_geniter():
yield from [1, 2, 3, 4]
print('finished')
for num in sample_geniter():
print(num)
print('hello')
ここではsample_geniterジェネレータ関数は、[0, 1, 2, 3]というリストに「処理を委譲」する。リストは反復可能オブジェクトなので、そのイテレータを使って、yield from式が実行されるたびにその要素を1つずつ返送してくれるということだ。
実行結果を以下に示す。
ここで重要なのは、yield from式は指定したサブジェネレータが持つ全ての値が返送されるまでは、構文上は処理が完了しないという点だ。そのため、上のコードでは全ての要素が列挙された後に、次の行が実行されて「finished」と表示され、yield式に到達することなくジェネレータイテレータが終了する。すると、StopIteration例外が発生するので、そこでfor文が終了する。
上のコードをfor文を使わずにwhile文を使って書き直したものを以下に示す。これを実行してみると、「print('finished')」行が実行された後にStopIteration例外が発生しているのが分かるはずだ(実行結果は省略)。
def sample_geniter():
yield from [0, 1, 2, 3]
print('finished')
mygeniter = sample_geniter()
num = next(mygeniter)
while True:
print(num)
num = next(mygeniter)
Copyright© Digital Advantage Corp. All Rights Reserved.