`
luozhaoyu
  • 浏览: 342633 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

python类中的__iter__, __next__与built-in的iter()函数举例

阅读更多
适才发现之前在pydev中使用的语法检查器是python3.2,而解释器是python2.7……罪过罪过,从此篇之后,不出意外都是使用python3.x版本解释器

本文主要举例介绍python的built-in函数iter,以及类中的两个函数__iter__,__next__。其中作为iterator的对象是类,而不是容器(因为容器或generator作为iterator对象很简单,这里不多说了)

iter函数有两种用法,一种是传一个参数,一种是传两个参数。返回的结果都是返回一个iterator对象。
先说传两个参数的,比如有
i1 = iter(itr, 'c')

这个意思是说,返回itr的iterator,而且在之后的迭代之中,迭代出来'c'就立马停止。对这个itr有什么要求呢?这个itr在这里必须是callable的,即要实现__call__函数

再说传一个参数,有
i2 = iter(itr)
这里itr必须实现__iter__函数,这个函数的返回值必须返回一个iterator对象

看例子:
class Itr(object):
    def __init__(self):
        self.result = ['a', 'b', 'c', 'd']
        self.i = iter(self.result)
        
        
    def __call__(self):
        res = next(self.i)
        print("__call__ called, which would return ", res)
        return res


    def __iter__(self):
        print("__iter__ called")
        return iter(self.result)

    
itr = Itr()
# i1必须是callable的,否则无法返回callable-iterator
i1 = iter(itr, 'c')
print("i1 = ", i1)
# i2只需要类实现__iter__函数即可返回
i2 = iter(itr)
print("i2 = ", i2)

for i in i1:
    print(i)

for i in i2:
    print(i)

输出结果是:
i1 =  <callable_iterator object at 0x1349710>
__iter__ called
i2 =  <list_iterator object at 0x133a090>
__call__ called, which would return  a
a
__call__ called, which would return  b
b
__call__ called, which would return  c
a
b
c
d

可以看到传入两个参数的i1的类型是一个callable_iterator,它每次在调用的时候,都会调用__cal__函数,并且最后到c就停止了。
而i2就简单的多,itr把自己类中一个容器的迭代器返回就可以了。

有朋友可能不满意,对上面的例子只是为了介绍iter()函数传两个参数的功能而写,如果真正想写一个iterator的类,需要使用__next__函数。这个函数每次返回一个值就可以实现迭代了。
class Next(object):
    def __init__(self, data = 1):
        self.data = data
        
        
    def __iter__(self):
        return self
    
    
    def __next__(self):
        print("__next__ called")
        if self.data > 5:
            raise StopIteration
        else:
            self.data += 1
            return self.data
for i in Next(3):
    print(i)

输出结果是:
__next__ called
4
__next__ called
5
__next__ called
6
__next__ called

很简单把。唯一需要注意下的就是__next__中必须控制iterator的结束条件,不然就死循环了。
分享到:
评论
2 楼 rushwoo 2015-09-13  
这样就可以了:
   def next(self):
        print("__next__ called")
        if self.data > 5:
            raise StopIteration
        else:
            self.data += 1
            return self.data
       
是不是和版本有关系
1 楼 rushwoo 2015-09-13  
报错啊:
    for i in Next(3):
TypeError: iter() returned non-iterator of type 'Next'

相关推荐

Global site tag (gtag.js) - Google Analytics