python迭代器

作者: 霡霂976447044 | 来源:发表于2019-02-16 17:06 被阅读7次

    for item in Iterable本质

    在理解迭代器之前,先知道for item in Iterable的执行过程,注意,并不是说for迭代后面必须要一个可迭代对象
    只要要迭代的对象能够调用iter()方法,正确返回迭代器即可

    1. 先通过iter()函数获取可迭代对象Iterable的 迭代器

    2 . 通过获取到的迭代器不断调用该迭代器next()方法来获取下一个值并将其赋值给item

    3 . 当遇到StopIteration的异常后循环结束

    这里提及到Iterable需要有两个方法可以调用 iter()和next() 方法,这两个方法对应对象的两个魔法函数
    __iter__以及__next____iter__要返回一个迭代器,__next__需要返回数据。下面来讲解这两个方法以及迭代器,可迭代对象的关系。

    可迭代对象(Iterable)

    Python中任意的对象,只要它定义了可以返回一个迭代器的__iter__方法。

    >>>from collections import Iterator,Iterable
    >>> class MyList(object):
    ...     def __init__(self):
    ...             self.container = []
    ...     def add(self, item):
    ...             self.container.append(item)
    ...     def __iter__(self):
    ...             """返回一个迭代器"""
    ...             # 我们暂时忽略如何构造一个迭代器对象
    ...             pass
    ...
    >>> mylist = MyList()
    >>> from collections import Iterable
    >>> isinstance(mylist, Iterable)
    True
    >>>
    # 这回测试发现添加了__iter__方法的mylist对象已经是一个可迭代对象了
    

    isinstance(mylist, Iterable)可以判断是否是迭代器。
    但是MyList对象还不能正常的工作,它虽然是一个可迭代对象但是并不能给for遍历,因为__iter__方法没有返回一个迭代器,需要__iter__返回一个迭代器。下面说一说迭代器如何实现。

    迭代器(Iterator)

    一个实现了__iter__方法和__next__方法的对象,就是迭代器。注:有些资料只说__next__方法,但是在pyhton3调用instance(Iterator)会返回False。
    迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据,实际上,在使用next()函数的时候,调用的就是迭代器对象的__next__函数
    所以,我们要想构造一个迭代器,就要实现它的__next__函数, 但是这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现iter方法,而iter方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的iter方法返回自身即可。
    实现一个简单的迭代器:

    class MyIterator(object):
        """自定义的迭代器"""
        def __init__(self, mylist):
            self.mylist = mylist
            # current用来记录当前访问到的位置
            self.current = 0
        def __next__(self):
            if self.current < len(self.mylist.items):
                item = self.mylist.items[self.current]
                self.current += 1
                return item
            else:
                raise StopIteration
        def __iter__(self):
            return self
    

    用可迭代对象封装迭代器:

    class MyList(object):
        """自定义的一个可迭代对象"""
        def __init__(self):
            self.items = []
        def add(self, val):
            self.items.append(val)
        def __iter__(self):
            myiterator = MyIterator(self)
            return myiterator
    

    Iterator和Iterable两者关系

    • python3中可迭代对象(Iterable)是实现了iter方法就可以,迭代器(Iterator)是实现了iter方法和next方法的对象才可以,也就是说迭代器一定是可迭代对象,反过来不可。
    • 一个对象可以同时既是可迭代对象又是迭代器,只要方法里有next(python3) 又有iter方法,惯用的做法是iter方法返回自己作为迭代器。
    • 要给for遍历 需要对象实现iter方法并且正确返回一个迭代器。
    • 如果一个对象定义了可以支持下标索引的__getitem__方法也是可以被for…in…循环的,但是isinstance(Iterable)却是错误的
    • for…in…后面不一定是可迭代对象,__getitem__也可以

    关于getitem和for迭代

    是在类中定义了这个getitem 方法,那么它的实例对象(假定为p),可以像这样
    p[key] 取值,当实例对象做p[key] 运算时,会调用类中的方法getitem
    一般如果想使用索引访问元素时,就可以在类中定义这个方法(getitem(self, key) )。
    下面是一个例子:

    class Mygetitem:
        def __init__(self, text):
            self.text = text
        def __getitem__(self, index):
            result = self.text[index].upper()
            return result
    p = Mygetitem('Python')
    for c in p:
        print(c)
    

    __getitem__遇到异常时候终止for循环

    isinstance(p, Iterable) = False
    

    并不是可迭代对象,有些资料说可以被for迭代的就是可迭代对象我认为是不正确的。
    Mygetitem是可以用iter(p)返回一个迭代器的。所以for迭代的本质是调用iter(Obj)得到一个迭代器,再调用里面的next()方法来

    相关文章

      网友评论

        本文标题:python迭代器

        本文链接:https://www.haomeiwen.com/subject/bfkieqtx.html