當前位置:編程學習大全網 - 源碼下載 - python的叠代器為什麽壹定要實現

python的叠代器為什麽壹定要實現

這是個和多態有關的問題,Python中關於叠代有兩個概念,第壹個是Iterable,第二個是Iterator,協議規定Iterable的__iter__方法會返回壹個Iterator, Iterator的__next__方法(Python 2裏是next)會返回下壹個叠代對象,如果叠代結束則拋出StopIteration異常。

同時,Iterator自己也是壹種Iterable,所以也需要實現Iterable的接口,也就是__iter__,這樣在for當中兩者都可以使用。Iterator的__iter__只需要返回自己就行了。這樣,下面的代碼就可以工作:

for i in my_list:

...

for i in iter(mylist):

...

for i in (v for v in mylist if v is not None):

...

Python中許多方法直接返回iterator,比如itertools裏面的izip等方法,如果Iterator自己不是Iterable的話,就很不方便,需要先返回壹個Iterable對象,再讓Iterable返回Iterator。生成器表達式也是壹個iterator,顯然對於生成器表達式直接使用for是非常重要的。

那麽為什麽不只保留Iterator的接口而還需要設計Iterable呢?許多對象比如list、dict,是可以重復遍歷的,甚至可以同時並發地進行遍歷,通過__iter__每次返回壹個獨立的叠代器,就可以保證不同的叠代過程不會互相影響。而生成器表達式之類的結果往往是壹次性的,不可以重復遍歷,所以直接返回壹個Iterator就好。讓Iterator也實現Iterable的兼容就可以很靈活地選擇返回哪壹種。

總結來說Iterator實現的__iter__是為了兼容Iterable的接口,從而讓Iterator成為Iterable的壹種實現。

補充壹下題主對於for的理解基本上是正確的,但仍然有壹點點偏差:for為了兼容性其實有兩種機制,如果對象有__iter__會使用叠代器,但是如果對象沒有__iter__,但是實現了__getitem__,會改用下標叠代的方式。我們可以試壹下:

>>> class NotIterable(object):

... def __init__(self, baselist):

... self._baselist = baselist

... def __getitem__(self, index):

... return self._baselist[index]

...

>>> t = NotIterable([1,2,3])

>>> for i in t:

... print i

...

1

2

3

>>> iter(t)

<iterator object at 0x0345E3D0>

當for發現沒有__iter__但是有__getitem__的時候,會從0開始依次讀取相應的下標,直到發生IndexError為止,這是壹種舊的叠代協議。iter方法也會處理這種情況,在不存在__iter__的時候,返回壹個下標叠代的iterator對象來代替。壹個重要的例子是str,字符串就是沒有__iter__接口的。

  • 上一篇:什麽小生意賺錢快
  • 下一篇:linux的內核運行原理是怎麽樣的呢?如何從開機,到加載內核鏡像到內存?
  • copyright 2024編程學習大全網