python3 - 可迭代对象和迭代器
迭代对象、迭代器协议
-
说到协议就不得不提一下,python中有个很重要的特性叫做鸭子类型, 打个比喻:当你看到一只鸟走起来像鸭子,游泳起来像鸭子,叫起来也想呀,那么这只鸟可以被成为鸭子
-
可迭代的对象:具有__iter__魔法方法。
-
迭代器:具有__iter__和__next__魔法方法。
我们先来了解一下python的可迭代、迭代器的基类源码
可迭代对象基类
迭代器协议基类
这里简单解释一下源码:
- slots: 弱引用
- @abstractmethod: 判断继承对象的子类对象是否完成它修饰下的方法。
- metaclass=ABCMeta:这里涉及到元类,ABCMeta控制对象的生成的过程。
- subclasshook:钩子方法,主要的意思:是否完成了__iter__或__iter__、__next__协议,完成则True否则抛异常。这里跟instance有着紧密的联系 (判断该对象是否是可迭代对象或迭代器对象)。
代码示范
当我们继承了Iterator和Iterable并完成相应协议(这里一定一定要完成特定的魔法方法,否则实例时会报错),那么就可以称为迭代器或者迭代对象
代码示范:
from collections.abc import Iterator, Iterable
class Iterable_demo(Iterable):
'''可迭代对象'''
def __init__(self, l: list):
self.l = l
def __iter__(self):
return Iterator_demo(iter(self.l))
class Iterator_demo(Iterator):
'''迭代器'''
def __init__(self, l):
self.l = l
def __iter__(self):
return self
def __next__(self):
while True:
try:
return next(self.l)
except StopIteration:
raise StopIteration
l = [1, 2, 3]
i = Iterable_demo(l)
# 调用for时, 自动调用i的__iter__魔方方法
for i in i:
print(i)
#打印1
#打印2
#打印3
tips: 由于python是动态语言,非常鼓励鸭子的特性。只要完成了__iter__或__iter__、__next__协议,那么就可以称为可迭代对象或迭代器,不需要JAVA那般继承基类(俗称天鹅特性)。