美文网首页
什么是生成器?

什么是生成器?

作者: 郭银蕾 | 来源:发表于2018-05-28 20:03 被阅读0次

第一次看到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。

相关文章

网友评论

      本文标题:什么是生成器?

      本文链接:https://www.haomeiwen.com/subject/kkhnjftx.html