Home > Article > Backend Development > How does Python\'s `send` function allow for two-way communication with generators?
Understanding the Role of "send" in Python Generators
The "yield" keyword in Python allows generators to yield values, allowing the caller to iterate over the generator's output. However, generators also provide a complementary function called "send", which offers an additional layer of control.
The "send" function, documented as "generator.send(value)", allows the caller to input a value into a generator that has just yielded. This input value becomes the result of the current yield expression. Importantly, it is distinct from the argument value passed to the generator function when it is first instantiated.
To illustrate, consider the following generator:
<code class="python">def double_inputs(): while True: x = yield # Pauses the generator yield x * 2 # Returns the doubled value</code>
Initially, calling next(gen) on the generator object gen advances its execution to the first yield statement. At this point, we can utilize the "send" function to input a value. For instance, executing gen.send(10) will set x to 10 and resume the generator, resulting in it yielding 20.
<code class="python">gen = double_inputs() next(gen) # Pause at first yield gen.send(10) # Send input value of 10 20</code>
This process can be repeated, allowing multiple inputs to be sent to the generator. It is worth noting that this capability cannot be achieved solely through the "yield" mechanism.
One practical application of the "send" function is in the context of Twisted's @defer.inlineCallbacks decorator. It enables the creation of functions that resemble standard procedural functions but can perform asynchronous computations and callbacks.
For example, using the "send" function, the following code can be modernized:
<code class="python"># Old approach with callbacks def doStuff(): returnDeferred = defer.Deferred() def gotNextResult(nextResult): returnDeferred.callback(nextResult / 10) def gotResult(result): takesTenSeconds(result * 10).addCallback(gotNextResult) takesTwoSeconds().addCallback(gotResult) return returnDeferred # New approach using @defer.inlineCallbacks @defer.inlineCallbacks def doStuff(): result = yield takesTwoSeconds() nextResult = yield takesTenSeconds(result * 10) defer.returnValue(nextResult / 10)</code>
By understanding the purpose and capabilities of the "send" function, developers can unlock the potential of generators in a wider range of programming scenarios.
The above is the detailed content of How does Python\'s `send` function allow for two-way communication with generators?. For more information, please follow other related articles on the PHP Chinese website!