码迷,mamicode.com
首页 > 编程语言 > 详细

Python的迭代器和生成器

时间:2015-12-04 22:40:33      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

先说迭代器,对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的就,在后台for语句对容器对象对象调用iteration()函数,这是python的内置函数,iter()会返回一个定义next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。在没有后续元素是,调用next()会抛出一个StopIteration异常

 

技术分享

上面说的都是python自带的容器对象,它们都实现了相应的迭代器方法,自定义类的遍历怎么实现,方法是:对这个类AClass,实现__iter__(self)方法,使其返回一个带有__next__(self)方法的对象就可以了。如果你在AClass刚好也定义了__next()__(self)方法,那在__iter__里只有返回self就可以。

__iter__()和next()方法

这两个方法是迭代器最基本的方法,一个 用来获得迭代器对象,一个用来获取容器中的下一个元素。

class MyRange(object):
  def __init__(self,n):
    self.idx=0
    self.n=n
    def __iter__(self):
    return self

  def next(self):
    if self.idx<self.n:
      val = self.idx
      self.idx +=1
      return val
    else:
      raise StopIteration()

  myRange = MyRange(3)
  for i in myRange:
    print i

myRange这个对象就是一个可迭代对象,同时它本身也是一个迭代器对象。

生成器

在Python中,使用生成器可以很方便的支持迭代器协议。生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态。

def Zrange(n):
  i = 0
  while i < n:
    yield i
    i+= 1
zrange = Zrange(3)
print zrange
print [i for i in zrange]

其实,生成器函数返回生成器的迭代器。 “生成器的迭代器”这个术语通常被称作”生成器”。要注意的是生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法,其中一个就是next()。如同迭代器一样,我们可以使用next()函数来获取下一个值。

下面就介绍生成器是怎么工作的:

def Zrange(n):
  print ‘beginning of Zrange‘
  i = 0
  while i < n:
    print ‘before yield‘,i
    yield i
    i += 1
    print ‘after yield‘,i
  print ‘endding of Zrange‘
zrange = Zrange(3)
print ‘-------------------------‘
print zrange.next()
print ‘------------------‘
print zrange.next()
print ‘------------------‘
print zrange.next()
print ‘------------------‘
print zrange.next()
print ‘------------------‘

通过结果可以看到:

  • 当调用生成器函数的时候,函数只是返回了一个生成器对象,并没有 执行。
  • 当next()方法第一次被调用的时候,生成器函数才开始执行,执行到yield语句处停止
    • next()方法的返回值就是yield语句处的参数(yielded value)
  • 当继续调用next()方法的时候,函数将接着上一次停止的yield语句处继续执行,并到下一个yield处停止;如果后面没有yield就抛出StopIteration异常

 

生成器的send()和close()方法

生成器中还有两个很重要的方法:send()和close()。

  • send(value):

从前面了解到,next()方法可以恢复生成器状态并继续执行,其实send()是除next()外另一个恢复生成器的方法。

Python 2.5中,yield语句变成了yield表达式,也就是说yield可以有一个值,而这个值就是send()方法的参数,所以send(None)和next()是等效的。同样,next()和send()的返回值都是yield语句处的参数(yielded value)

关于send()方法需要注意的是:调用send传入非None值前,生成器必须处于挂起状态,否则将抛出异常。也就是说,第一次调用时,要使用next()语句或send(None),因为没有yield语句来接收这个值。

  • close():

这个方法用于关闭生成器,对关闭的生成器后再次调用next或send将抛出StopIteration异常。

Python的迭代器和生成器

标签:

原文地址:http://www.cnblogs.com/deng-qiang/p/5020556.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!