32

我熟悉 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

在研究状态机和协程时,我在此博客的代码示例中遇到了这一点。

4

3 回答 3

39

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

cr.send(1)

在您的示例中,这将为每次分配1c

cr.next()等效于cr.send(None)

于 2010-01-07T17:38:57.797 回答
12

您可以使用该send函数将值发送到生成器。

如果你执行:

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

然后yield将返回 5,因此生成器内部c将是 5。

此外,如果您调用p.next()yield将返回None

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

于 2010-01-07T17:38:22.327 回答
0
  • yield根据生成器函数中定义的逻辑返回数据流。
  • 但是, send(val) 是一种从生成器函数外部传递所需值的方法。

p.next() 在 python3 中不起作用,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

于 2020-06-09T06:14:15.700 回答