python的迭代器為什麼一定要實現 iter 方法?

時間 2021-05-30 05:38:52

1樓:劉昕宸

劉昕宸:徹底搞懂Python的__iter__和__next__,Iterable和Iteration

__iter__與__next__:

__iter__: 返回乙個迭代器物件,該物件是乙個實現了__next__的物件。該方法為容器類所擁有,類似於迭代器模式中Aggregate類的createIterator方法。

__next__: 顧名思義,返回當前迭代器的下乙個迭代器,並且不想繼續有迭代的情況下丟擲乙個StopIteration的異常。該方法為迭代器類所擁有,類似於Iterator類的next方法。

Iterable(可迭代物件) --> 指的是容器類,即需要迭代的物件

Iterable是能夠一次性返回其成員的物件。 常見Iterable包括所有的序列型別(如list,str和tuple)以及一些非序列型別,如dict和檔案,以及任何定義了__iter__()方法或__getitem__()的類的物件(可以把自己的成員乙個乙個返回(或者說遍歷自己的成員)的一類物件)。

Iterables可以用於for迴圈中,也可以用於許多需要序列的地方(zip(),map(),…))。 當乙個iterable(可迭代物件)作為引數傳遞給內建函式__iter__時,它返回該物件的迭代器iterator。當使用iterables時,通常不需要顯式呼叫iter()或者自己處理iterator物件,for語句為你自動執行,建立乙個臨時的未命名變數來儲存該iterable(可迭代物件)的迭代器循iterator,然後開始遍歷

Iterator(迭代器) --> 指的是迭代器,即用於迭代的工具

Iterator通過重複呼叫__next__()來實現對後繼元素的遍歷,如果沒有後繼元素仍然呼叫__next__會引起StopIteration exception

Iterator需要實現返回自己的__iter__(),所以Iterator也是Iterable,可以用在大多數使用Iterable的場合

可以通過將容器物件(也就是Iterable,比如list)傳遞給iter()或者for迴圈來獲得Iterator物件。

總結:

Python中 list,truple,str,dict這些都可以被迭代(Iterable),但他們並不是迭代器(Iterator),可以使用iter()函式獲得它們的Iterator

從使用角度來說:

可以使用for來遍歷的,都是Iterable。

可以使用next來遍歷的,都是Iterator。

從實現角度來說

Iterator物件的__iter__需要返回其本身,__next__用於實現返回容器中下乙個元素的迭代器。

Iterable物件只實現了__iter__或者__getitem__(這種隨機訪問都可以實現了,那迭代器訪問模式肯定也是可以的),能讓容器內各個元素分別都能獲得就可以了。

舉個栗子:

>>>x=

[1,2

,3]>>>y=

iter(x

)>>>z=

iter(x

)>>>

next(y

)1>>>next(y

)2>>>next(z

)1>>>type(x

)

'list

'>>>>type(y

)

'list_iterator

'>>>>type

(iter(y

))

'list_iterator

'>對於乙個list(它是Iterable,而不是Iterator),對其呼叫iter或者呼叫它的__iter__()方法會返回它的迭代器list_iterator(類似於C++中的List::iterator)

然後我們就可以使用next來對這個list_iterator操作了。

而用for遍歷list時,會自動給list呼叫iter獲得它的迭代器物件list_iterator,再進行方式的遍歷。

2樓:

A container can provide an iterator that provides access to its elements in order.

iter(iterable): Return an iterator over the elements of an iterable value

next(iterator): Return the next element in an iterator

Ex.>>> s = [3,4,5]

>>> t = iter(s)

>>> next(t)

>>> next(t)

3樓:T-mac

先明確定義:

什麼是Iterable(可迭代物件)?實現了__iter__方法,並返回迭代器的物件;

2. 或者實現了__getitem__方法,並且可以通過下標從0開始依次取值的物件;取值結束後丟擲IndexError;

什麼是Iterator(迭代器)?實現了next()方法或者__next__()的物件;

回答

因為在python的所有迭代場景中所作用的物件必須是可迭代物件(Iterable),因此迭代器(Iterator)要想在迭代場景中使用,就必須是Iterable物件;要成為Iterable物件就必須遵守Iterable協議,通過實現__iter__函式來滿足Iterable協議,從而成為Iterable物件。個人認為,迭代器實現__iter_函式的目的是為了相容python已有的迭代場景和工具,例如:for迴圈、列表解析、map、sum、zip等等。

如果迭代器不實現__iter_方法的話,上述函式和工具都無法用來對該迭代器進行迭代,只能通過人工呼叫next()方法來進行迭代,這與python "簡潔統一" 的設計原則是相違背的,所以迭代器要實現__iter__方法。

4樓:肖恩

個人理解:__iter__()方法返回乙個迭代物件,在使用for ... in ...

這種迭代操作時,對這類可迭代物件進行一種特殊操作(比如反覆呼叫,直到引發StopIteration異常)。

自定義的迭代器背後的操作步驟實際上是這樣的:

比如進行迭代操作

classA:

...def__iter__(self):

returnx

def__next__(self):

...a = A()

foriina:

...在for迴圈裡,首先會去尋找__init__(self)方法返回的那個物件x(一般在正經的自定義迭代器中x會是self,然而也可以不是)。然後去呼叫那個物件x的__next__(self)方法(__next__()方法只是next()函式的乙個介面,可以讓next()幹任何事情,和迭代無關)。

如果你在定義A時,__iter__(self)方法返回的x是iter('abcd'),而__next__(self)返回值為1時,你會發現next(a)得到的結果為1,但是list(a)得到的結果是['a', 'b', 'c', 'd'],完全避開了自定義的__next__()方法。

因此只有實現了__iter__(self)方法的物件才是迭代器,和有沒有__next__()方法沒啥實質性的關係。

5樓:

__iter__

使類例項 Iterable

next()

使類例項是迭代器物件

注:『迭代器物件』跟『Iterable』是兩個東東喲。

題主提到,for語句來迴圈,它實際的工作流程是:

先判斷被迴圈的是否是Iterable,如果不是,儘管你實現了next(),它扔不會去呼叫,會直接報異常

所以,題主提到的

我是這樣理解的:首先呼叫iter獲取需要迭代的物件,然後呼叫該物件的next方法,不知道理解對不對

是對的。只不過,python直譯器是嚴格遵守『先呼叫iter來獲取迭代物件,然後再呼叫物件next』這個步驟來的,所以,你也必須實現__iter__。

一點拙見

有一定的基礎,如何學python?

裸睡的豬 該怎麼學,那要看你想用它幹什麼,做任何事都是有目的性的!你基礎不好,但是會用django框架了,說明前面可能學的不是很紮實,為了嘗鮮!如果你現在的狀態是想轉行到Python的話,那你自己應該清楚 基礎對面試的重要性,基礎決定將來的高度!你現在來提問也說明你看到自己的短板,所以如果你想轉行那...

為什麼 look forward to 後面一定要接 doing,其中的 doing 是非謂語動詞嗎?

柱蹄兒 固定搭配 look forward to something。something是啥?我也不知道。我只知道doing可以當名詞用。 look forward to的to是介詞,介詞賓語必須是乙個名詞性的成分 want to do 的to是提示不定式的乙個助詞 particle,亦譯作小品詞 ...

為什麼年輕一定打工?

當然你也可以有其他的一些選擇,比如自己嘗試去做一點小生意,打工不是唯一的出路,在社會經驗不足 個人資源儲備較低的情況下最優化的選擇還是做打工人。為了生活,走入社會,積累經驗,不一定啊。每個人的生活都市不一樣的,看你怎麼選擇對不對。你可以現在打工,積攢一點積蓄,然後拿你的積蓄去自己做點小買賣什麼的。因...