Python 可迭代的對象與迭代器的對比
什么是迭代?迭代是指按需一次獲取一個數(shù)據(jù)。是否可以迭代,可以通過是否可以使用for循環(huán)取值來進行簡單的判斷。更準(zhǔn)確的判斷是使用iter()函數(shù),這是一個Python內(nèi)置函數(shù)。
可迭代的對象
iter()函數(shù)的作用如下:
如果對象實現(xiàn)了__iter__方法,那么就調(diào)用它,獲取一個迭代器。比如:
- def __iter__(self):
- return SentenceIterator(self.words)
如果對象沒有實現(xiàn)__iter__但是實現(xiàn)了__getitem__方法,那么就創(chuàng)建一個迭代器,嘗試從索引0開始獲取元素。
如果嘗試獲取元素失敗,就會拋出TypeError異常。
可迭代的對象,就是使用iter()函數(shù)判斷,滿足前面2點的對象。
任何Python序列都是可以迭代的,因為它們都實現(xiàn)了__getitem__方法。
迭代器
從前面iter()函數(shù)的作用可以發(fā)現(xiàn),迭代器是從可迭代的對象中獲取的。
如果對象本身是可迭代的,就調(diào)用__iter__方法獲取一個迭代器。
如果對象不可迭代但是實現(xiàn)了__getitem__方法,那么就會創(chuàng)建一個迭代器。
比如可以使用iter()函數(shù)把列表轉(zhuǎn)換為迭代器:
- >>> test_list = [1, 2, 3]
- >>> print(type(test_list))
- <class 'list'>
- >>> test_iter = iter(test_list)
- >>> print(type(test_iter))
- <class 'list_iterator'>
迭代器可以使用for循環(huán)遍歷:
- for x in test_iter:
- print(x)
也可以使用while循環(huán)遍歷:
- while True:
- try:
- print(next(test_iter))
- except StopIteration:
- del test_iter
- break
- next()函數(shù)用于獲取迭代器下一個元素。
- 沒有元素了,迭代器會拋出StopIteration異常。
標(biāo)準(zhǔn)的迭代器接口有兩個方法:
- __next__返回下一個元素。
- __iter__返回self,以便在應(yīng)該使用可迭代對象的地方使用迭代器,比如for循環(huán)中。
- def __iter__(self):
- return self
迭代器的準(zhǔn)確定義是:迭代器是這樣的對象,它實現(xiàn)了無參數(shù)的__next__方法,返回序列中的下一個元素;如果沒有元素了,那么拋出StopIteration異常。Python中的迭代器還實現(xiàn)了__iter__方法,因此迭代器也是可以迭代的。
最后,通過對比可以發(fā)現(xiàn),可迭代對象的__iter__返回的是迭代器:
- def __iter__(self):
- return SentenceIterator(self.words)
迭代器的__iter__返回的是self:
- class SentenceIterator:
- def __iter__(self):
- return self
而且迭代器還需要有__next__方法。
從這一點就能清楚看出它們的區(qū)別了。
需要特別注意的是,可迭代的對象一定不能是自身的迭代器,也就是說,可迭代對象必須實現(xiàn)__iter__方法,但是不能實現(xiàn)__next__方法。否則會讓設(shè)計模式變得混亂不堪。
參考資料:
《流暢的Python》第14章 可迭代的對象、迭代器和生成器
https://www.runoob.com/python3/python3-iterator-generator.html