小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
Python中的生成器其实远远不止生成器这么简单。
先前我们使用了生成器和生成器表达式。然后可以让生成器多次产出值交由我们使用。但Python的生成器中还有一个非常中要的函数:send。
在这里我们不再把生成器函数称之为生成器,而是协程了。
send函数可以让我们的程序不再仅仅接受协程产生的值,还能将值发送到协程中。也就是说,我们的程序和协程之间可以相互交互。
具体来说send函数可以传入一个参数,这个参数会成为yield表达式的值。通过在协程中读取yield语句的值,可以获取
假设我们需要写一个程序,用于计算统计输入的奇数和偶数的数量。使用协程来实现
def count():
even = 0
odd = 0
while True:
cur = yield even, odd
if cur % 2 == 0:
even += 1
else:
odd += 1
当我们尝试把代码写了就会发现,有哪里不对劲,为什么先前可以使用next?send能不能直接使用?我们在纯粹把这个东西作为生成器的时候是根本就没关注过这些。
情况是这样的,先前在使用next函数的时候,会被当作发送了None值给生成器。现在我们使用send则可以直接从send函数的返回值中获取数据,而不会再使用next函数。
不过呢,像上面写的这个生成器,如果我们直接使用send函数是会报错的。因为send函数的效果是把值交给yield表达式,而函数最开始不是处于yield表达式的位置。
所以这里需要一个关键的操作,在创建函数的时候,使用一次next函数,让函数暂停到yield表达式的位置,之后才可以使用send。这个过程一般被称为预激活。
所以我们使用协程可以像下面这样:
corutine = count()
next(corutine)
while True:
x = int(input())
print(corutine.send(x))
至此,我们完成了协程的使用。