什么是生成器?

第一次看到Python代码中出现yield关键字时,一脸懵逼,完全理解不了这个。网上查下解释,函数中出现了yield关键字,则调用该函数时会返回一个生成器。那到底什么是生成器呢?我们经常看到类似下面的代码

def count(n):

     x = 0

     while x < n:

         yield x

         x += 1

for i in count(5):

    print i


这段代码执行后打印序列0到4,所以我一开始以为这个生成器就是生成一个序列呀。那这跟迭代器有什么区别呢?我们来看下迭代器的例子:

class CountIter:

    def __init__(self, n):

        self.n = n

    def __iter__(self):

        self.x = -1

        return self

    def next(self):  # For Python 2.x

        self.x += 1

        if self.x < self.n:

            return self.x

        else:

            raise StopIteration

for i in CountIter(5):

    print i


CountIter类就是一个迭代器,它的__iter__()方法返回可迭代对象,next()方法则执行下一轮迭代(注:在Python 3.x里是__next__()方法)。上面的代码执行后也会打印序列0到4,看上去跟之前的生成器效果一样,就是代码长一点。不仅如此,生成器自带next()方法,而且在越界时也会抛出StopIteration异常。

close()方法

顾名思义,close()方法就是关闭生成器。生成器被关闭后,再次调用next()方法,不管能否遇到yield关键字,都会立即抛出StopIteration异常。

gen = (x for x in range(5))

gen.close()

gen.next()  # StopIteration

send()方法

这是我认为生成器最重要的功能,我们可以通过send()方法,向生成器内部传递参数。我们来看个例子:

def count(n):

    x = 0

    while x < n:

        value = yield x

        if value is not None:

            print 'Received value: %s' %value

        x += 1


还是之前的count函数,唯一的区别是我们将”yield x”的值赋给了变量value,并将其打印出来。如何给value传值呢?

gen = count(5)

print gen.next()  # print 0

print gen.send('Hello')  # Received value: Hello, then print 1


我们先调用next()方法,让代码执行到yield关键字(这步必须要),当前打印出0。然后当我们调用”gen.send(‘Hello’)”时,字符串’Hello’就被传入生成器中,并作为yield关键字的执行结果赋给变量”value”,所以控制台会打印出”Received value: Hello”。然后代码继续执行,直到下一次遇到yield关键字后暂定,此时生成器返回的是1。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 住的这个小区也建好几年了,怎么周围一直在装修,钻啊钻啊。于是开大音乐,挡住钻的声音,周期性重复的声音实在是乱人心绪...
    KevinCool阅读 839评论 1 1
  • 1.1==,is的使用 ·is是比较两个引用是否指向了同一个对象(引用比较)。 ·==是比较两个对象是否相等。 1...
    TENG书阅读 746评论 0 0
  • 1 年轻人都想干大事,我也不例外。带着这样的傲气踏入职场的大门,刚进门,自尊心就被劈碎了。 一开始是做图书营销编辑...
    蜡笔滴爱十年阅读 177评论 0 0
  • 90年前后是各类经典神话剧的井喷期,在闭塞的改革开放初期,大众还见不得多识不得广,对于物质和精神生活双匮乏,这眼花...
    三文鱼子阅读 156评论 0 0
  • 曾经我说:树上的树叶是何其的悲哀,他们一生都只能呆在一个地方,永远都不能不能努力地向上,去靠近那片阳光地带。 现在...
    苏歆匿阅读 407评论 0 0