yield作为赋值操作符的作用是什么?myVar = (yield)

34

我对使用yield返回值已经很熟悉了,主要得益于这个问题的解答。

但是当yield出现在赋值语句的右侧时,它是做什么用的呢?

@coroutine
def protocol(target=None):
   while True:
       c = (yield)

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        cr.next()
        return cr 
    return start

我在研究状态机和协程时,在这篇博客的代码示例中发现了这个。

3个回答

40

yield语句用于函数中,将该函数转换为“生成器”(创建迭代器的函数)。通常通过调用next()方法来恢复生成器的执行。然而,也可以通过调用send()方法而不是next()方法来向函数发送值以恢复它:

cr.send(1)
在您的示例中,每次都会将值1赋给c。 cr.next() 实际上等同于 cr.send(None)

1
请注意,在能够调用生成器的 send() 方法之前,您必须先调用 next() 方法来启动它,否则您将会收到一个 TypeError 错误,提示:TypeError: can't send non-None value to a just-started generator - Caumons

12

您可以使用send函数向生成器发送值。

如果执行以下操作:

p = protocol()
p.next() # advance to the yield statement, otherwise I can't call send
p.send(5)

如果调用p.next()yield将返回None

此外,如果yield返回5,则生成器内部的c将为5。

您可以在此处找到更多信息。


0
  • yield 根据生成器函数内定义的逻辑返回数据流。
  • 然而,send(val) 是一种从生成器函数外部传递所需值的方法。

p.next() 在 Python 3 中不起作用,next(p) 可以在 Python 2 和 3 中使用(内置)

p.next() 在 Python 3 中无法使用,会出现以下错误,但在 Python 2 中仍然可以使用。

Error: 'generator' object has no attribute 'next'

这是一个演示:
def fun(li):
  if len(li):
    val = yield len(li)
    print(val)
    yield None
    

g = fun([1,2,3,4,5,6])
next(g) # len(li) i.e. 6 is assigned to val
g.send(8) #  8 is assigned to val


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接