可迭代对象Iterable、迭代器Iterator

如果一个对象实现了__iter__方法,那么就是可迭代的Iterable

Python的collections模块提供了Iterable和Iterator这两个抽象类,可以让我们检测一个对象是否是可迭代的以及是否是迭代器

In [16]: class MyIterable(object):
    ...:     def __iter__(self):
    ...:         return None
    ...:

In [17]: myiter = MyIterable()

In [18]: isinstance(myiter, Iterable)
Out[18]: True

我们经常用for来遍历一些对象例如list、tuple和file,这种遍历即为迭代,那这些对象也即是可迭代对象。

总言之,能被for遍历的对象都是可迭代对象,但是可迭代对象不一定能被for遍历,有点绕。

In [22]: for i in myiter:
    ...:     print(i)
    ...:
------------------------------------------------------------
TypeError                                 Traceback (most re
<ipython-input-22-dd58bed4c9dc> in <module>()
----> 1 for i in myiter:
      2     print(i)
      3

TypeError: iter() returned non-iterator of type 'NoneType'

如上所示,我们自定义的MyIter类的实例无法被for遍历,究其原因,就是for在遍历一个对象时,需要先用内置函数iter将该对象转换为一个迭代器,然后才能进行遍历;而我们上述的MyIter类的__iter__方法返回的却是一个None。


说到迭代器,就要讲下迭代器协议:  对于一个对象,使用next方法来调用它,要么返回迭代的下一项,要么返回一个StopIteration异常表示迭代终止。

迭代器就是实现了迭代器协议的对象,也即实现了__next__方法(python2中是next方法),经过测试发现,只实现__next__方法还是不够的。

In [25]: class MyIterator(object):
    ...:
    ...:     def __next__(self):
    ...:         return 1
    ...:

In [26]: myiterator = MyIterator()

In [27]: isinstance(myiterator, Iterator)
Out[27]: False

还需要实现__iter__方法才行。

In [31]: class MyIterator(object):
    ...:
    ...:     def __iter__(self):
    ...:         return self
    ...:
    ...:     def __next__(self):
    ...:         return 1
    ...:

In [32]: myiterator = MyIterator()

In [33]: isinstance(myiterator, Iterator)
Out[33]: True
所以,我得出一个新的结论: 迭代器必是可迭代对象, 反之不成立。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值