from collections.abc import Iterable,Iterator
class Iterable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __iter__(self):
while False:
yield None
@classmethod
def __subclasshook__(cls, C):
if cls is Iterable:
return _check_methods(C, "__iter__")
return NotImplemented
class Iterator(Iterable):
__slots__ = ()
@abstractmethod
def __next__(self):
'Return the next item from the iterator. When exhausted, raise StopIteration'
raise StopIteration
def __iter__(self):
return self
@classmethod
def __subclasshook__(cls, C):
if cls is Iterator:
return _check_methods(C, '__iter__', '__next__')
return NotImplemented
迭代器Iterator需要实现两个魔法方法,next和iter,而可迭代对象中,只要实现了__iter__就可以算可迭代对象。
可迭代对象中的__iter__魔法函数必须返回一个迭代器Iterator对象(也就是必须实现__next__这个魔法方法)。
可迭代对象 → 返回迭代器 → 使用next(迭代器) → 抛错
迭代器实现__iter__和__next__方法。
可迭代对象,如果实现了__iter__和__getitem__,这个时候就不会调用__getitem__了,并且在for循环中通过隐式调用内置的next()来进行遍历。
当类里面没有实现__iter__但是实现了__getitem__的话,python解释器会自动生成默认的迭代器,然后这个迭代器会利用__getitem__来进行遍历。
连续两次对一个可迭代对象进行遍历,会重新创建一个迭代器从最开始迭代。
from collections.abc import Iterable,Iterator
class Company:
def __init__(self,name):
self.name = name
def __iter__(self):
return Iter(self.name)
class Iter(Iterator):
def __init__(self,name):
self.name = name
self.index = 0
def __next__(self):
try:
name = self.name[self.index]
except IndexError:
raise StopIteration
self.index+=1
return name
name_list = ["小明","小红","小张"]
name = Company(name_list)
Iterable_name = iter(name)
while True:
try:
name = next(Iterable_name)
print(name)
except StopIteration:
break
小明
小红
小张