python的可迭代對象和迭代器

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章