小编典典

Python 生成器上的“发送”函数的目的是什么?

all

有人可以举个例子说明为什么存在与 Python 生成器函数相关的“发送”函数吗?我完全理解收益函数。但是,发送功能让我感到困惑。这个方法的文档很复杂:

generator.send(value)

恢复执行并将值“结束”到生成器函数中。value 参数成为当前 yield 表达式的结果。send()
方法返回生成器产生的下一个值,或者如果生成器退出而没有产生另一个值,则引发 StopIteration。

这意味着什么?我认为值是函数的输入?短语“send() 方法返回生成器产生的下一个值”似乎也是 yield 函数的确切用途;yield
返回生成器产生的下一个值…

有人可以给我一个使用 send 的生成器的示例,它可以完成 yield 无法完成的事情吗?


阅读 59

收藏
2022-06-20

共1个答案

小编典典

它用于将值发送到刚刚产生的生成器中。这是一个人为的(无用的)解释性示例:

>>> def double_inputs():
...     while True:
...         x = yield
...         yield x * 2
...
>>> gen = double_inputs()
>>> next(gen)       # run up to the first yield
>>> gen.send(10)    # goes into 'x' variable
20
>>> next(gen)       # run up to the next yield
>>> gen.send(6)     # goes into 'x' again
12
>>> next(gen)       # run up to the next yield
>>> gen.send(94.3)  # goes into 'x' again
188.5999999999999

你不能只用yield.

至于它为什么有用,我见过的最好的用例之一是 Twisted 的@defer.inlineCallbacks. 本质上,它允许您编写这样的函数:

@defer.inlineCallbacks
def doStuff():
    result = yield takesTwoSeconds()
    nextResult = yield takesTenSeconds(result * 10)
    defer.returnValue(nextResult / 10)

发生的情况是takesTwoSeconds()返回 a Deferred,这是一个承诺稍后将计算一个值的值。Twisted
可以在另一个线程中运行计算。计算完成后,它会将其传递给 deferred,然后将值发送回doStuff()函数。因此,doStuff()can
最终看起来或多或少像一个普通的程序函数,除了它可以进行各种计算和回调等。在此功能之前的替代方法是执行以下操作:

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

它更加复杂和笨拙。

2022-06-20