标准的迭代器接口有两个方法:
__next__:返回一个可用元素,没有的时候抛出stoplteration异常
__iter__:返回self,以便在应该使用可迭代对象的地方使用迭代器,例如for循环中。
class eg:
def __init__(self,text):
self.text = text
self.sub_text = text.split(' ')
def __iter__(self): #实现了iter方法,此方法返回一个迭代器egiterator
return egiterator(self.sub_text)
class egiterator: #实现了next和iter方法
def __init__(self,sub_text):
self.sub_text = sub_text
self.index = 0
def __next__(self):
try:
subtext = self.sub_text[self.index]
except IndexError:
raise StopIteration()
self.index += 1
return subtext
def __iter__(self):
return self
odd = eg("hi, can you help me?")
for i in odd:
print(i)
注:可见,功能是和上篇文章‘无聊’是一样的,上篇文章是python自动帮我们创建了迭代器。
通过两篇文章,我们需要明确可迭代的对象和迭代器间的关系:
python从可迭代的对象中获取迭代器
iter从我们创建的迭代器类中获取迭代器,getitem是python内部自动创建迭代器 。
上面实现的简化版(通常使用版本):
class eg3:
def __init__(self,text):
self.text = text
self.sub_text = text.split(' ')
def __iter__(self):
for item in self.sub_text:
yield item #函数中存在yield关键字,代表该函数是生成器函数
#调用生成器函数时,会产生生成器对象;也就是说生成器函数是生成器工厂。
#更简化版
class eg4:
def __init__(self,text):
self.text = text
self.sub_text = text.split(' ')
def __iter__(self):
yield from self.sub_text
odd = eg3("this is a book!")
for i in odd:
print(i)
print()
odd1 = eg4("this is a book!")
for i in odd1:
print(i)
进一步,用生成器表达式可改写成:
class Iter:
def __init__(self,text):
self.text = text
self.sub_text = text.split(' ')
def __iter__(self):
return (item for item in self.sub_text)