yield fromの概要
Python
3.3で導入されたyield from
構文は、ジェネレーターやコルーチン間で効率的に処理を委譲するためのツールです。これにより、サブジェネレーターからの値や例外を自動的に受け渡すことができ、複雑なfor
ループの代わりに簡潔なコードを記述できます。
使い方と動作原理
通常、ジェネレーターをネストして使用する場合、サブジェネレーターから値を手動で反復する必要があります。以下の例を見てみましょう。
def generator():
for i in range(5):
yield i
def outer():
for value in generator():
yield value
このコードは、サブジェネレーターgenerator
から値をouter
で再度反復して返します。yield from
を使うと、これを次のように簡素化できます。
def outer():
yield from generator()
この変更により、反復処理の手間が省かれ、可読性が向上します。
非同期I/Oとコルーチン
yield from
は非同期プログラミングでも役立ちます。コルーチン間でデータを送受信する際や例外を扱うとき、yield from
を使うことで双方向の通信を簡潔に実装できます。また、ネストされたジェネレーターやコルーチンが完了したときに適切に処理を終了する仕組みも提供します。
async def handle_client(reader, writer):
data = await reader.read(100)
writer.write(data)
await writer.drain()
writer.close()
上記の例はyield from
に似た非同期I/Oの例であり、yield from
はこれと同様にコルーチンを使ったプログラムで簡潔な処理を可能にします。
実用例
再帰的なデータ構造の処理
再帰的なジェネレーターを使って、ネストされたデータ構造を探索するケースがあります。yield from
を使うと、次のように簡単に記述できます。
def traverse_tree(node):
if not node.children:
yield node
for child in node.children:
yield from traverse_tree(child)
この例では、木構造の全てのリーフノードを再帰的に取得しています。
まとめ
yield from
は、ジェネレーターの委譲や非同期処理を効率化し、Python
コードを簡潔かつ効率的にします。特に、複雑なジェネレーターの操作やネストされた処理をシンプルにする効果があります。