標籤:dict sub item print ssm 字串 rds 大型 ext
#14.1 Sentence類第一版,單詞序列
#栗子14-1 吧句子劃分為單詞序列
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 __getitem__(self, item):
return self.words[item]
def __len__(self): #為了完善序列,我們實現__len__方法,為了讓對象可迭代,沒必要實現這個方法
return len(self.words)
def __repr__(self):
return ‘Sentence(%s)‘ % reprlib.repr(self.text) #產生大型資料結構的簡略字串表示
#栗子14-2 測試Sentence是否可迭代
s = Sentence(‘"The tiem has come,",the walrus said,‘)
print(s) #Sentence(‘"The tiem ha... walrus said,‘)
for word in s:
print(word)
‘‘‘
The
tiem
has
come
the
walrus
said
‘‘‘
print(list(s)) #[‘The‘, ‘tiem‘, ‘has‘, ‘come‘, ‘the‘, ‘walrus‘, ‘said‘]
#【分析】序列可迭代的原因
‘‘‘
(1)檢查內建對象是否實現了__iter__方法,如果實現了就調用他,擷取一個迭代器
(2)如果沒有實現__iter__方法,但是實現了__getitem__方法,Python會建立一個迭代器,嘗試按順序(從索引0開始)擷取元素
(3)如果嘗試失敗,Python跑出TypeError異常,通常會提示"C object is not itrable"
‘‘‘
#14.2 可迭代對象和迭代器對比
# Iterable 和 Iterator 抽象基類。前者是後者的父類,後者在前者__iter__的基礎上,新加了__next__方法。
#Iterator 裡有個方法
import abc
@classmethod
def __subclasshook__(cls,C):
if cls is abc.Iterator:
if (any("__next__" in B.__dict__ for B in C.__mro__) and
any("__iter__" in B.__dict__ for B in C.__mro__)):
return True
return NotImplemented
#考慮到Lib/types.py中的建議,以及Lib/_collections_abc.py中的邏輯實現,檢查對象x是否為迭代器最好的方式是調用isinstance(x,abc.Iterator)。得益於Iterator.__subclasshook__方法,即使對象x
#...所屬的類不是Iterator類的真實子類或者虛擬子類,也能這麼檢查
#使用栗子14-1 中的類,用iter()函數構建迭代器,用next()函數使用迭代器
s3 = Sentence(‘Pig and Pepper‘)
it = iter(s3)
print(it) #<iterator object at 0x0000000002948A58>
print(next(it)) #Pig
print(next(it)) #and
print(next(it)) #Pepper
#print(next(it)) #StopIteration
print(list(it)) #[] 到頭後,迭代器沒用了
print(list(iter(s3))) #[‘Pig‘, ‘and‘, ‘Pepper‘] 要想再次迭代,要重新構建迭代器
#因為內建的 iter(...) 函數會對序列做特殊處理,所以第 1 版 Sentence 類可以迭代。接下來要實現標準的可迭代協議
【Python】【控制流程程】【迭代對象、迭代器、產生器】