可迭代的對象
使用 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》 --第十四章