可迭代的对象
使用 iter 内置函数可以获取迭代器的对象。如果对象实现了能返回迭代器的__iter__ 方法,那么对象就是可迭代的。序列都可以迭代;
迭代器
Python 从可迭代的对象中获取迭代器, 它实现了无参数的 __next__ 方法,返回序列中的下一个元素;如果没有元素了,那么 抛出 StopIteration 异常。Python 中的迭代器还实现了__iter__ 方法,因此迭代器也可以迭代。
一般来说, 我们可以同时实现__next__以及__iter__方法, 如下例:
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence():
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text)
self.index = 0
#利用生成器函数实现可迭代对象
def __iter__(self):
for text in self.words:
print("这里是__iter__")
yield text
def __next__(self):
try:
print("这里是__next__")
word = self.words[self.index]
except IndexError:
raise StopIteration()
self.index+=1
return word
def __len__(self):
return len(self.words)
def __repr__(self):
return "Sentence(%s)" % reprlib.repr(self.text) #解析压缩字符串以利于输出
strText = "hello, I'm kangkang, how are you!"
s = Sentence(strText)
for i in s:
print(i)
for i in range(len(s)):
print(next(s))
##################################
这里是__iter__
hello
这里是__iter__
I
这里是__iter__
m
...
这里是__next__
hello
这里是__next__
I
这里是__next__
m
...
而根据《设计模式:可复用面向对象软件的基础》一书讲解迭代器设计模式时,在“适用性”一节中说:
迭代器模式可用来:
访问一个聚合对象的内容而无需暴露它的内部表示
支持对聚合对象的多种遍历
为遍历不同的聚合结构提供一个统一的接口(即支持多态迭代)
为了“支持多种遍历”,必须能从同一个可迭代的实例中获取多个独立的迭代器,而且各个迭代器要能维护自身的内部状态,因此这一模式正确的实现方式是,每次调用iter(my_iterable) 都新建一个独立的迭代器.
故: 可迭代的对象一定不能是自身的迭代器。也就是说,可迭代的对象必须实现__iter__ 方法,但不能实现 __next__ 方法。
另一方面,迭代器应该一直可以迭代。迭代器的 __iter__ 方法应该返回自身。
适用于Python的可迭代对象例子:
import re
import reprlib
RE_WORD = re.compile('\w+')
class Sentence():
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text)
#利用生成器函数实现可迭代对象
def __iter__(self):
for text in self.words:
yield text
def __len__(self):
return len(self.words)
def __repr__(self):
return "Sentence(%s)" % reprlib.repr(self.text) #解析压缩字符串以利于输出
strText = "hello, I'm kangkang, how are you!"
s = Sentence(strText)
for i in s:
print(i)
######################################
hello
I
m
kangkang
how
are
you
参考文献: 《Fluent Python》 --第十四章