Python中的可迭代对象和迭代器

1、可迭代对象

  1.1、可迭代对象概念

    可迭代对象,最直观的感觉就是可以使用for来循环迭代每一个元素。例如Python内置的类型:str、list、tuple、dict等类型的对象,都是可迭代对象。

    其实for循环迭代可迭代对象,是先调用可迭代对象的__iter__()方法,得到迭代器,然后再依次调用迭代器的__next__()方法获取元素的。

  1.2、可迭代对象的判断

    判断一个对象是不是“可迭代对象”,可以使用“collection.abc.Iterable”,即“isinstance(对象, Iterable)”来判断是否是可迭代对象,值是True则是可迭代对象,值是False则不是可迭代对象

  1.3、可迭代对象必须方法

      1.3.1、__iter__()

        a) 要使一个对象是可迭代对象,那么该对象必须要有__iter__()方法。但是只是有__iter__()方法,也不能保证能被for循环调用,只有当__iter__()方法返回一个迭代器的时候,才能被for循环迭代调用。总之,我们在__iter__()方法中,要保证返回一个迭代器,不然没什么意义。

        b) 如果没有__iter__()方法,那么就肯定不是可迭代对象,不过可能也能被for循环调用。

  1.4、可迭代对象的使用

    1.4.1、for中使用

      只要自定义的对象中有__iter__()方法,那么该对象就是可迭代对象,即使用“isinstance(自定义对象, Iterable)”就会返回True。

      可迭代对象不一定能直接被for循环调用迭代。只有自定义对象的__iter__()方法返回值是一个迭代器的时候,这个可迭代对象才能被for进行迭代调用。

      for循环调用可迭代对象的步骤:

        a) 调用可迭代对象的__iter__()方法,得到对应的迭代器

        b) 调用迭代器的__next__()方法,得到每一个元素,直到出现StopIteration异常抛出

    1.4.2、iter()函数使用

      可以使用“iter(可迭代对象)”来得到一个【迭代器】

  1.5、自定义可迭代对象示例

      我们在自定义可迭代对象的时候,最好继承Iterable接口,当然了,也可以不用继承


from collections.abc import Iterable, Iterator


class MyIterable:
def __init__(self, data: Iterable):
self.__data = data

def __iter__(self):
"""
必须提供该方法,并且该方法的返回值要是一个迭代器(生成器也属于迭代器)
"""
yield from self.__data


if __name__ == '__main__':
obj = MyIterable("abc")
print(obj)
print(iter(obj))
for _ in obj:
print(_)
 

 2、迭代器

  2.1、迭代器概念

    迭代器是实际上能被for调用或者被list调用的对象。一般我们自定义的可迭代对象中的__iter__()方法,返回的就是迭代器。

    生成器也是一种迭代器。

  2.2、迭代器的判断

    判断一个对象是不是“迭代器对象”,可以使用“collection.abc.Iterator”,即“isinstance(对象, Iterator)”来判断是否是迭代器,值是True则是迭代器,值是False则不是迭代器。

  2.3、迭代器必须方法

      只要一个对象定义了__next__()和__iter__()方法,即使两个的方法体是空的,那么该对象也是迭代器。即“isinstance(对象, Iterator)”的返回值是True

    2.3.1、  __next__()

      迭代器的__next__()方法,返回迭代器的下一个元素

    2.3.2、 __iter__()

      迭代器的__iter__()方法,一般都是返回自己

  2.4、迭代器的使用

    2.4.1、for中使用

      for直接迭代迭代器,每次获取一个元素。

    2.4.2、next()函数使用

      next()函数调用迭代器,每次获取一个元素。

    2.4.3、list()函数使用

      list()函数调用迭代器,把迭代器中的所有元素都取出来,放在列表中。

  2.5、自定义迭代器示例

  

from collections.abc import Iterable, Iterator


# 可迭代对象
class MyIterable:
    def __init__(self, data: Iterable):
        self.__data = data

    def __iter__(self):
        return MyIterator(self.__data)


# 迭代器
class MyIterator:
    def __init__(self, data: Iterable):
        self.__data = data
        self.__index = 0

    def __iter__(self):
        return self

    def __next__(self):
        try:
            value = self.__data[self.__index]
            self.__index += 1
        except IndexError:
            raise StopIteration
        return value


if __name__ == '__main__':
    obj = MyIterable("abc")
    print(obj)
    print(iter(obj))
    for _ in obj:
        print(_)

    输出:

<__main__.MyIterable object at 0x01F55110>
<__main__.MyIterator object at 0x01F50130>
a
b
c

 

3、可迭代对象和迭代器汇总

  3.1、图示

 

 

  

 

posted @ 2023-01-10 11:10  JCL_1023  阅读(995)  评论(0编辑  收藏  举报