协程可以在Python中产生值吗?

时间:2018-11-08 10:02:21

标签: python python-3.x generator pipeline coroutine

所以我了解generatorscoroutines的工作方式。概括地说,generators产生数据,coroutines消耗数据。现在,我想做的就是结合这两个功能。

我已经定义了一个coroutine,它接收到一个list作为输入,然后一次尝试从列表中一次**yield**个项目,就像generator那样

这是我的代码-

def coroutine():
    print('Starting coroutine')
    value = (yield)
    for i in value:
        yield i



c=coroutine()
c.__next__()
c.send([1,2,3,4,5])


for val in c:
    print(val)

问题是,第一个列表项丢失了。 value 1 并未从协程返回。

根据我的理解,流程应该如下。

  1. c=coroutine() ---->声明coroutine而不启动它。
  2. c.__next__() ---->这将启动coroutine,并前进到行value = (yield)并在此处停止。
  3. c.send([1,2,3,4,5]) ---->这会将新的list传递给等待的协程,即value = (yield)。协程现在进入for循环中的下一个 yield 语句。
  4. 主程序中的
  5. for循环应该接收它最初传递的列表的每个项目。但这不会发生。

能否请您解释原因?我尝试这样做的原因是生成管道。每个组件都将接收项目,对其进行修改,然后将其提供给管道中的下一个协程。

请帮助。

编辑--------------------

输出如下-

Starting coroutine
2
3
4
5

1 个答案:

答案 0 :(得分:1)

您丢失了当调用send时,corrutine会一直运行到下一个yield的情况,因此会被调用,所以,如果您这样做:

c=coroutine()
c.__next__()
print(c.send([1,2,3,4,5]))


for val in c:
    print(val)

您将看到如何打印缺失值(如在send调用中产生的那样)

这里有live example

对于您想要的行为,您可以在Corrutine中添加一个额外的yield语句:

def coroutine():
    print('Starting coroutine')
    value = (yield)
    yield
    for i in value:
        yield i