首页 > 代码库 > (补)4.生成器知识点补充和梳理

(补)4.生成器知识点补充和梳理

这篇文章是对上一篇讲生成器和迭代器的文章做的补充。

回顾一下概念,什么是生成器?

生成器就是一个包涵yield关键字的函数,当这个函数被调用的时候,函数体中的代码不会被执行!

而是返回了一个迭代器。

每请求一个值,就回执行一次生成器中的代码,直到遇到yield或者return。

其中yield意为着生成一个值,而return意为着生成器要停止执行,不再生成任何东西,这是yield和return本质上的区别。


其实函数式生成器,可以当做是分文两部分组成的,生成器的函数和生成器的迭代器。


下面是关于生成器常用方法详解:

next()老生常谈,没什么好说的了,从生成器中获取一个新的值,这个值是从生成器的yeild中返回出来的。


send() 和next方法作用很相似,都可以从生成器中取一个值,和next不同的是,send方法可以给yield传值,然后在通过yield传递给生成器中的变量,也就是间接的给生成器内部的变量赋值(通过下面的例子可以看到)


注意!!在使用send方法有一个特别的注意事项!就是第一次调用生成器时,请使用next方法或者是send(None)send一个空值,如果send其他的值会出错!!这是因为没有yield语句去接收这个值!

(简单的说,就是在函数的执行状态被“挂起”send方法才会起到相应的作用。)


最后,在细说下前面写的那个简化版的“生产者与消费者”模型。

1 import time

2 def consumer(name):

3     print ‘我是%s,准备开始吃包子了‘%(name)

4     while True:

5         stuffed_bun = yield

6         time.sleep(1)

7         print "%s很开心的把%s吃掉了" %(name,stuffed_bun)

8 def producer():

9     p1 = consumer("suhaozhi")

10    p2 = consumer("ayumi")

11    p1.next()   #执行next方法后,死循环开始

12    p2.next()   

13    for i in range(10):

14        time.sleep(1)

15        p1.send("包子%s" %(i))  #通过send给yield赋值,yield在将值赋给stuffed_bun

16        p2.send("包子%s" %(i))

17 producer()


首先,第一步开始执行producer生产者函数,这个函数使用生成器生成了两个“消费者”,首先要明确一个概念!!其中第9行和第10行,只是定义了两个生成器,并不会执行consumer函数中的任何内容。

定义好了两个生成器之后,11行和12行执行的next方法,启动这两个生成器,这时,回到consumer函数,开始执行死循环,执行到yield时候开始将执行状态“挂起”准备接收producer函数(生产者)传的值。

15行16行的代码,就是将值传递给consumer函数中的yield对应的stuffed_bun变量,当yield收到了来15,16行的send方法传递值后,执行第6行和第7行,然后回到producer函数的for循环然后继续执行15行和16行的代码,继续通过yield接收send方法发来的值,给stuffed_bun这个变量赋值....一直到producer(生产者)中的for循环执行结束。



本文出自 “reBiRTH” 博客,请务必保留此出处http://suhaozhi.blog.51cto.com/7272298/1909032

(补)4.生成器知识点补充和梳理