迭代器和生成器都是很重要的知识,因为在后边的同步异步都要用到.
python的迭代协议构成了迭代器.
迭代器是访问集合内元素的一种方式,一般用来遍历数据.
要记住 迭代器和 下标的访问方式不一样,迭代器没有返回值,它取值的方式就是用next().
迭代器提供了一种惰性访问数据方式,访问数据时候才能计算和返回数据.
list 的访问方式是用 getitem 协议,
list 和迭代器 可以用for 循环都是实现迭代协议(iter)这个方法.
我们查找下源码 :
from collections.abc import Iterable,Iterator
class Iterable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __iter__(self):
while False:
yield None
只要有这个 __iter__抽象魔法函数一定可迭代, 咱们再看下Iterator
class Iterator(Iterable):
__slots__ = ()
def __iter__(self):
return self
@abstractmethod
def __next__(self):
raise StopIteration
大家看下 Iterator 比Iterable 多了一个抽象魔法函数 next,
并且继承了Iterable也重写了iter 抽象方法.
其中 iter 是返回个迭代对象,next 返回下一个数据,在我们访问数据的时候就变成一个迭代器,
迭代器只是比迭代对象多了抽象魔法函数 next, 要记住迭代器也是迭代对象.
咱们 看下 list 源码 :
class list(object):
"""
list() -> new empty list
list(iterable) -> new list initialized from iterable's items
"""
def append(self, p_object): # real signature unknown; restored from __doc__
""" L.append(object) -> None -- append object to end """
pass
def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass
list 只重写了 iter 这个魔法函数,所以list 只是个可迭代对象.
具体有什么区别,我们看下边的例子:
>>> x = [1,2,3]
>>> y = iter(x) #inter是特殊的方法可以把迭代对象变成迭代器,可以查下
>>> z = iter(x)
>>> next(y) #通过inter方法变成迭代器之后就可以用next方法,如果用 next(x)会报错
1
>>> next(y)
2
>>> next(z)
1
>>> type(x)
<class 'list'>
>>> type(y) #inter是特殊的方法可以把迭代对象变成迭代器,可以查下
<class 'list_iterator'>
上边的iter 和next 与魔法函数的__inter__ 和__next__ 是不一样的,自己可以查下.
只要迭代对象调用了next方法就可以变成迭代器.
迭代器是可以循环输出,直到报错为止.
有人说了 list 是个迭代对象,为什么可以用for循环.
for i in [0,2,3]:
print(i)
1.首先list 是迭代对象,它只是重写了iter魔法函数,
2.那为什么可以循环输出呢,答案是for 循环自带next 魔法函数
咱们debug 看下:
Iterator = {ABCMeta} <class 'collections.abc.Iterator'>
Iterable = {ABCMeta} <class 'collections.abc.Iterable'>
list 用到了for循环的 next,变成个迭代器可以循环输出.
for i in [1,2,3]:
print(i)
就相当于 :
a=iter([1,2,3,4])
while True:
try:
x = next(a);
except StopIteration:
break
print(x)
先调用了iter 从迭代对象变成一个迭代器,然后调用了next 方法.进行遍历.
有什么问题请在下边留言, 谢谢