Python迭代器与生成器详解(2)

>>> lst_iter = iter([1,2,3]) >>> lst_iter.__next__() 1 >>> lst_iter.__next__() 2 >>> lst_iter.__next__() 3 >>> lst_iter.__next__() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>>

这里注意:这里的__next__()方法和内置函数next(iterator, default=None)不是一个东西;(内置函数next(iterator, default=None)也可以返回迭代器的下一个值)

c) 而for循环可以捕获StopIteration异常并结束循环;

总结一下:

a)for....in iterable,会通过调用iter(iterable)函数(实际上,首先调用的对象的__iter__()方法),返回一个迭代器iterator;

b)每次循环,调用一次对象的__next__(self),直到最后一个值,再次调用会触发StopIteration

c)for循环捕捉到StopIteration,从而结束循环

上面说了这么多,到底什么是迭代器Iterator呢?

任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值;

既然知道了什么迭代器,那我们自定义一个迭代器玩玩:

1 class Iterator_test(object): 2 def __init__(self, data): 3 self.data = data 4 self.index = len(data) 5 6 def __iter__(self): 7 return self 8 9 def __next__(self): 10 if self.index <= 0 : 11 raise StopIteration 12 self.index -= 1 13 return self.data[self.index] 14 15 iterator_winter = Iterator_test('abcde') 16 17 for item in iterator_winter: 18 print(item)

View Code

如何判断一个对象是一个迭代器对象呢?两个方法:

1)通过内置函数next(iterator, default=None),可以看到next的第一个参数必须是迭代器;所以迭代器也可以认为是可以被next()函数调用的对象

2)通过collection中的Iterator类型判断

>>> from collections import Iterator >>> >>> isinstance([1,2,3], Iterator) False >>> isinstance(iter([1,2,3]), Iterator) True >>> isinstance([1,2,3].__iter__(), Iterator) True >>>

这里大家会不会有个疑问:

对于迭代器而言,看上去作用的不就是__next__方法嘛,__iter__好像没什么卵用,干嘛还需要__iter__方法呢?

我们知道,python中迭代是通过for循环实现的,而for循环的循环对象必须是一个可迭代对象Iterable,而Iterable必须是一个实现了__iter__方法的对象;知道为什么需要__iter__魔术方法了吧;

那么我就是想自定义一个没有实现__iter__方法的迭代器可以吗?可以,像下面这样:

class Iterable_test(object): def __init__(self, data): self.data = data def __iter__(self): return Iterator_test(self.data) class Iterator_test(object): def __init__(self, data): self.data = data self.index = len(data) def __next__(self): if self.index <= 0 : raise StopIteration self.index -= 1 return self.data[self.index] iterator_winter = Iterable_test('abcde') for item in iterator_winter: print(item)

View Code

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/e6a0c31b6f1b387c60317b92283f0191.html