python可迭代对象 迭代器 生成器

可迭代对象

具有 _iter_ 方法的对象,即为可迭代对象。

In [9]: from collections.abc import Iterable, Iterator

In [10]: class Xhz:
    ...:     def __iter__():
    ...:         pass

In [11]: isinstance(Xhz(), Iterable)
Out[11]: True

In [12]: isinstance(Xhz(), Iterator)
Out[12]: False

实际上 __iter__方法需要返回一个迭代器对象。

迭代器对象

同时实现了 _iter_ 和 _next_ 方法的对象,即为迭代器对象。

In [15]: class Xhz:
    ...:     def __iter__():
    ...:         return self
    ...:
    ...:     def __next__():
    ...:         return 3

In [16]: isinstance(Xhz(), Iterator)
Out[16]: True

In [17]: isinstance(Xhz(), Iterable)
Out[17]: True
  1. 迭代器对象一定是可迭代对象
  2. 可迭代对象不一定是迭代器对象
  3. 可迭代对象的 _iter_ 方法是用来产生迭代器对象的。
    例如,我们经常使用的list ,就是一个可迭代对象,而不是迭代器对象。
In [18]: a = []

In [19]: isinstance(a, Iterable)
Out[19]: True

In [20]: isinstance(a, Iterator)
Out[20]: False

内置函数 iter 的作用就是调用参数的 _iter_ 方法,获取该方法返回的迭代器对象。
内置函数 next 的作用就是调用参数迭代器的 _next_ 方法,获取返回的元素。

In [51]: a = [1, 3, 5]

In [52]: b = iter(a)

In [53]: b
Out[53]: <list_iterator at 0x1b245ba5160>

In [54]: next(b)
Out[54]: 1

In [55]: next(b)
Out[55]: 3

In [56]: next(b)
Out[56]: 5

实际上 Iterator 是 Iterable 的子类

In [21]: issubclass(Iterator, Iterable)
Out[21]: True

生成器

生成器对象其实也是一个迭代器对象

In [61]: def gen():
    ...:     yield 3
In [62]: a = gen()
In [63]: type(a)
Out[63]: generator
In [64]: isinstance(a, Iterator)
Out[64]: True

所以可迭代对象的 _iter_ 方法可以直接返回一个生成器

In [66]: class Xhz:
    ...:     def __iter__(self):
    ...:         yield 3
    ...:         yield 4

In [67]: for i in Xhz():
    ...:     print(i)
3
4

yield from 语法用于生成器里面嵌套生成器,下面两段代码是等价的

def gen_one():
    subgen = range(10)
    yield from subgen
def gen_two():
    subgen = range(10)
    for item in subgen:
        yield item

yield from 后面也可以跟可迭代对象
python可迭代对象 迭代器 生成器_第1张图片
yield from 的另一个作用就是在调用者和内层生成器之间开辟了一条双向通道,外层调用者通过send()发送的消息可以直接到达内层生成器,内层生成器通过yield返回的数据也会直接返回给外层的调用者
python可迭代对象 迭代器 生成器_第2张图片

在生成器中使用return

return表示生成器迭代完成,通过迭代的方式并不能拿到生成器中return的返回值。
python可迭代对象 迭代器 生成器_第3张图片
那是不是表达生成器中return值并没有意义呢?其实不是的,看下面的代码
python可迭代对象 迭代器 生成器_第4张图片
从上面可以看出,生成器中return的值会传递给 yield from 表达式。

你可能感兴趣的:(python,开发语言)