我很熟悉yield返回值,主要归功于this question
但是当它位于作业的右侧时,屈服会做什么?
@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
我在this blog的代码示例中遇到了这个问题,同时研究了状态机和协同程序。
答案 0 :(得分:36)
函数中使用的yield
语句将该函数转换为“生成器”(创建迭代器的函数)。通常通过调用next()
来恢复生成的迭代器。但是,可以通过调用方法send()
而不是next()
来恢复该值来向函数发送值:
cr.send(1)
在您的示例中,每次都会将值1
分配给c
。
cr.next()
实际上等同于cr.send(None)
答案 1 :(得分:11)
您可以使用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
。
您可以找到更多信息here。
答案 2 :(得分:0)
yield
根据生成器函数中定义的逻辑返回数据流。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