Python ジェネレーターの領域では、yield キーワードが基礎として立っており、反復可能なシーケンス。ただし、yield と並んで、もう 1 つの謎めいた関数が影に潜んでいます。send.
ドキュメントには、send が「実行を再開し、値をジェネレータ関数に「送信」する」と書かれた不可解な説明が記載されています。これにより、その目的と利回りとの関係の両方について疑問が生じます。
値は入力と出力ですか?
最初の困惑は、値が入力として機能するという概念から生じます。ジェネレーター関数に。ただし、ドキュメントでは、send がジェネレーターによって生成された次の値を返すことも示唆しています。これは、yield によって実行されるのと同じ機能ではありませんか?
真の目的を明らかにする
この謎を解決する鍵は、send によって値の注入が可能になることを理解することにあります。発電機は降伏しています。次の例を考えてみましょう。
<code class="python">def double_inputs(): while True: x = yield yield x * 2</code>
このジェネレーターは、値を受信するため (出力) と値を返すため (出力) の 2 つの穴があるブラック ボックスであると想像してください。 next(generator) を呼び出してジェネレーターを開始すると、ジェネレーターは最初の yield ステートメントで一時停止し、入力を待ちます。
これで、send を使用してジェネレーターに値をフィードできるようになります。値は一時的に x 変数に保存されます。ジェネレーターを再開すると、最初の yield ステートメント以降のコードが実行され、入力値が効果的に 2 倍になり、yield を通じて返されます。
Yield に値しない例
yield では実現できない送信の固有の機能については、次の点を考慮してください:
<code class="python">gen = double_inputs() next(gen) # run up to the first yield gen.send(10) # goes into 'x' variable</code>
このコードは、実質的に値 10 をジェネレーターに挿入します。その後、実行が再開され、2 倍の値である 20 が返されます。この一連のアクションは、yield のみを使用して実現することは不可能です。
send を使用した Twisted の魔法
send の実際的なアプリケーションの 1 つは、Twisted の @defer.inlineCallbacks デコレーターによって例示されています。これにより、将来の値を表す Deferred オブジェクトを生成する関数を作成できます。基礎となるフレームワークはこれらの Deferred オブジェクトをインターセプトし、必要な計算をバックグラウンドで実行します。
計算が完了すると、フレームワークは結果をジェネレーターに送り返し、実行の再開をシミュレートし、ジェネレーターが後続の処理を続行できるようにします。操作。
結論
Python ジェネレーターの send 関数を使用すると、yield ステートメントで一時停止されているジェネレーターに値を注入できます。この機能により、Twisted の @defer.inlineCallbacks デコレーターが示すように、高度な制御フローが可能になり、非同期プログラミングが簡素化されます。 yield と並行して送信する独自の目的を理解することで、Python コードでジェネレーターの可能性を最大限に引き出すことができます。
以上がPython ジェネレーターの「send」関数の本当の目的は何ですか?また、「yield」キーワードとの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。