3、 迭代器和可迭的

作者:灵剑
链接:https://www.zhihu.com/question/44015086/answer/119281039
来源:知乎
Python中关于迭代有两个概念,第一个是Iterable(可迭代的),第二个是Iterator(迭代器),协议规定Iterable的iter方法会返回一个Iterator, Iterator的__next__方法(Python 2里是next)会返回下一个迭代对象,如果迭代结束则抛出StopIteration异常。同时,Iterator自己也是一种Iterable。
那么为什么不只保留Iterator的接口而还需要设计Iterable呢?许多对象比如list、dict,是可以重复遍历的,甚至可以同时并发地进行遍历,通过iter每次返回一个独立的迭代器,就可以保证不同的迭代过程不会互相影响。而生成器表达式之类的结果往往是一次性的,不可以重复遍历,所以直接返回一个Iterator就好。让Iterator也实现Iterable的兼容就可以很灵活地选择返回哪一种。
类中的iter不仅仅是返回自身实例,也可以返回其他可迭代对象的实例,这样就实现了委托迭代。
for为了兼容性其实有两种机制,如果对象有iter会使用迭代器,但是如果对象没有iter,但是实现了getitem,会改用下标迭代的方式,从0开始依次读取相应的下标,直到发生IndexError为止,这是一种旧的迭代协议。
先判断被循环的是否是Iterable,如果不是,尽管你实现了next,它扔不会去调用,会直接报异常

image.png

提供了可扩展的迭代器接口;
对列表迭代带来了性能上的增强;
在字典迭代中性能提升;
创建真正的迭代接口,而不是原来的随即对象访问;
与所有已经存在的用户定义的类以及扩展得模拟序列和映射的对象向后兼容;
迭代非序列集合(例如映射和文件)时,可以创建更简洁可读的代码

一、 分清了下面几个概念,也就搞懂了Python的迭代器:
1.可迭代类(class collections.abc.Iterable)
提供了__iter__()这个方法的类 都是可迭代类,或者__getitem__()这个方法的类,也是可迭代类
2.迭代器类(Iterator)
同时提供__iter__()和__next__()这两个方法的类(迭代器类,一定是可迭代类,因为他实现了__iter__()方法)
(迭代器类,要比可迭代类多实现一个__next__()方法)
3.可迭代对象:
简单来讲,就是那些 list,str和tuple用这些定义的对象,都是可迭代对,因为他们都实现了__iter__()方法或是__getitem__方法。
4.迭代器对象:
代表数据流的对象——迭代器。
你可以把可迭代对象,当成一个容器(collections)。那么你可以制造一个迭代器类,用他生成的迭代器对象,可以帮你一个一个从容器里取出数据。所以,迭代器必须实现__next__()方法.

因为迭代器也实现了__iter__()方法,所以 它当然也是一个可迭代类。

迭代器对象是如何得到的呢,d = iter(kkk)就可以把kkk的迭代对象(‘K’)取出来了
(注意1.这里的iter()函数,不同于__iter__():2,kkk必须是一个可迭代对象,比如 kkk=[1,2,3,4,5,100]这样的,或是kkk内部实现了__iter__()方法。)
一般来说,当你自己定义一个可迭代类时,我们希望有一个迭代器对象来取它自己的数据,所以__iter__()只需要返回自己就可以了,即retrun self.

只实现了__next__()方法的类

class test():
    def __init__(self,data=1):
        self.data = data

    def __next__(self):
        if self.data > 5:
            raise StopIteration
        else:
            self.data+=1
            return self.data

t = test(3)   
for i in range(3):
    print(t.__next__())

python之__iter__()与__next__()

你可能感兴趣的:(3、 迭代器和可迭的)