协程

    协程的技巧是将“yield”关键字写在表达式的右边。下面是一个打印出所发送的值的协程例子:

    首先要调用“next”来将协程推进。你可以看到它执行了一个打印。最终,函数进行到“yield”表达式了,然后就会等待唤醒。之后,每次有值被发送过来,协程就会从“yield”处唤醒,将值复制给val并打印出它。
    使用方法可以关闭这个协程。

    1. >>> co.close()
    2. >>> co.send(4)
    3. Traceback (most recent call last):
    4. File "<stdin>", line 1, in <module>
    5. StopIteration
    1. 创建一个名为“square”的协程,它会打印出所发送的值的平方。
    2. 创建一个名为“minimize”的协程,它会保存并打印出所发送的值中最小的一个值。

    协程可以用在部署数据管道中,其中一个协程会发送数据到下一个在数据管道中的协程。协程使用send()方法来将数据压入管道。

    这是一个小型管道,值会从生产者协程发送到消费者协程打印出来:

    正如上面所说,在发送任何数据前调用“next”是非常重要的一个步骤。

    1. >>> cons = consumer()
    2. >>> prod = producer(cons)
    3. >>> next(prod)
    4. Producer ready
    5. Consumer ready
    6. Consumer got 1
    7. >>> prod.send(2)
    8. Consumer got 4
    9. >>> prod.send(3)
    10. Consumer got 9

    同样的,对于协程来说,数据可以被发送到不同的地方。下面的例子是部署了两个消费者,第一个它只会打印0-10之间的内容,第二个则是10-20。

    1. >>> con1 = consumer('Consumer 1', 00, 10)
    2. >>> con2 = consumer('Consumer 2', 10, 20)
    3. >>> prod = producer([con1, con2])
    4. >>> next(prod)
    5. Producer ready
    6. >>> next(con1)
    7. Consumer 1 ready
    8. Consumer 2 ready
    9. >>> prod.send(1)
    10. Consumer 1 got 1
    11. >>> prod.send(2)
    12. Consumer 1 got 4
    13. >>> prod.send(3)
    14. Consumer 1 got 9
    15. >>> prod.send(4)
    16. Consumer 2 got 16
    17. >>> prod.close()
    18. Consumer 1 closed
    19. Consumer 2 closed

    数据被发送到所有的消费者中,但只有第二个执行了打印命令。注意这里使用的“GeneratorExit”异常。一般都会用捕获异常的方式来通知下游协程这个管道没有用了,赶紧关闭了吧。

    1. 部署一个生产者-消费者管道,生产者会将值的平方发送给两个消费者。其中一个会储存并打印出所发送的值中最小的一个,另一个则是最大的一个。