小编典典

python生成器“发送”功能的目的?

python

有人可以给我一个为什么与Python生成器函数关联的“发送”函数存在的示例吗?我完全了解yield函数。但是,发送功能使我感到困惑。有关此方法的文档非常复杂:

generator.send(value)

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

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

有人可以给我一个使用send的生成器的示例,该生成完成了某些无法完成的工作吗?


阅读 194

收藏
2020-12-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可以在另一个线程中运行计算。计算完成后,将其传递给延迟的对象,然后将值发送回doStuff()函数。因此doStuff(),除了可以执行各种计算和回调等操作外,最终看起来或多或少都像普通的过程函数。此功能之前的替代方法是:

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

这更加令人费解和笨拙。

2020-12-20