理解迭代器是學習Python重要的里程碑。這篇文章帶你理解基於類的迭代器的實現。
Python相比於其他語言,更加簡潔、好看。請看下面的for-in循環:
迭代列表 numbers 每一項並打印。
那這個循環背後的構造是怎麼做到的呢,我們自己實現一個對象,能迭代嗎?
理解了Python的迭代器的接口,就可以自己實現
只要創建的對象實現 __iter__ 和 __next__ 方法,就可以用 for-in 循環迭代對象。
實現一個永遠不會停的迭代器
我們準備開始寫一個類,這個類實現了迭代器的接口中的兩個方法。
輸出:
RepeatForever 和 RepeatForeverIterator 一起構成了我們這個永不停止的迭代器。RepeatForever 實現了 __iter__ 方法,此方法返回一個迭代器對象 RepeatForeverIterator,這個迭代器對象定義了 __next__ 方法。
實例化 RepeatForever('hello') 後使用for-in 循環執行,實際上調用了迭代器的 __next__ 方法。
為了解釋 for-in 調用的細節,我們可以自己實現一個看看它是怎麼調用的。
使用了更熟悉的 while 循環,每次循環,都調用迭代器對象 RepeatForeverIterator 的__next__ 方法。輸出結果和用 for-in是一致的。
其實和數據庫的 cursor 對象類似,不用一次把結果都讀入到內存中,而是一次獲取一行,處理一行。這樣能夠節省內存,增大運行效率。
使用 for-in 語法,我們就不用自己編寫 while 語法,不需要知道迭代器怎麼獲取,調用迭代器哪個方法。 用更抽象的語言描述就是迭代器提供了簡潔的接口,允許處理容器的每個元素,而不必知道其中的內部結構。
你不需要知道要迭代的類型,列表,試圖,字典,元組都不用考慮,只要一項一項的處理數據。
Python 提供了內置方法 iter() 和 next() 處理迭代器。iter() 方法接受的參數是支持迭代器接口的對象。返回迭代器對象,然後調用 next() 方法就每次能夠獲取到迭代器的下一個元素。
一個類實現迭代器
以上的例子可以用一個類就能實現。
類 RepeatForever 的方法 __iter__ 返回自身引用 self。
類自己又定義了 __next__ 方法,並返回值 self.value。
限制迭代次數
限制迭代次數需要在迭代器方法 __next__ 中拋出異常,raise StopIteration。for-in 會為我們處理這個異常,然後停止執行。
RepeatBounded 構造函數中,初始化了計數器變量 count 為 0
__next__ 方法每次調用時,計數器變量 count 會加1。方法開頭判斷如果計數器變量 count 大於等於 max_count 時,達到最大循環次數,拋出異常 StopIteration,停止迭代。
輸出:
閱讀更多 趣喜歡編程 的文章