python生成器中的send()方法和next()方法
在使用异步IO时,generator是最基本的实现方法。python生成器有两种主要方法,一种是send,另一种是next。今天,让我们来看看两者的用法和联系。在每个代码中,第一个next调用相当于启动生成器,它将从生成器函数的第一行代码开始执行,直到第一次执行yield句子(第4行),跳出生成器函数。然后,第二个next调用,进入生成器函数,从yield句子的下一个句子(第5行)开始执行,然后重新运行到yield句子。执行后,跳出生成器函数,再次调用next,等等。

在这里,我们以经典的生产者-消费者模型为例(摘自廖雪峰的博客)
defconsumer(): r=0 foriinxrange(3): yieldr r='200OK'+str(i) c=consumer() n1=c.next() n2=c.next() n3=c.next()
事实上,next()在某种意义上与send()相似。不同的是,send()可以传递yield表达值,而next()不能传递特定值,只能传递none。因此,我们可以把它看作是c.next() 和 c.send(None) 功能是一样的。
第一次调用时,请使用next()语句或send(None),非None值不能用send发送,否则会出错,因为没有Pythone yield语句接收此值。
相关推荐:Python视频教程
以下是send执行的顺序。请记住,n1 = yield r这句话是从右到左执行的。第一次sendd(None)(对应11行)启动生成器,从生成器函数的第一行代码开始执行,跳出生成器函数,直到第一次执行yield(对应第4行)。N1在此过程中没有定义。
当运行到send(1)时,进入生成器函数,此时,yield r被视为一个整体,赋值并传回。此时,它相当于将1赋值给n1,但不执行yield部分。继续执行yield的下一个句子,然后重新运行到yield句子。执行后,跳出生成器函数。也就是说,与next相比,send只开始增加一个赋值动作,其他操作过程是相同的。
defconsumer():
r='here'
whileTrue:
n1=yieldr#这里的等式右侧相当于一个整体,接受回传值
ifnotn1:
return
print('[CONSUMER]Consuming%s...'%n1)
r='%d00OK'%n1
defproduce(c):
aa=c.send(None)
n=0
whilen<5:
n=n+1
print('[PRODUCER]Producing%s...'%n)
r1=c.send(n)
print('[PRODUCER]Consumerreturn:%s'%r1)
c.close()
c=consumer()
produce(c)运行结果:
[PRODUCER]Producing... [CONSUMER]consuming... [PRODUCER]Consumerreturn:100OK [PRODUCER]Producing2... [CONSUMER]consuming2... [PRODUCER]Consumerreturn:200OK [PRODUCER]Producing3... [CONSUMER]consuming3... [PRODUCER]Consumerreturn:300OK [PRODUCER]Producing4... [CONSUMER]consuming... [PRODUCER]Consumerreturn:400OK [PRODUCER]Producing5... [CONSUMER]consuming5... [PRODUCER]Consumerreturn:500OK
创建Python生成器的两种方法
