Python迭代器、生成器、裝飾器深刻解讀

前言

首先,明確可迭代對象、迭代器和生成器這三個概念。

可迭代對象(Iterable)

可迭代對象(Iterable Object),簡單的來理解就是可使用 for 來循環遍歷的對象。好比常見的 list、set和dict。html

可迭代對象具備__iter__ 方法,用於返回一個迭代器,或者定義了 getitem 方法,能夠按 index 索引的對象(而且可以在沒有值時拋出一個 IndexError 異常),所以,可迭代對象就是可以經過它獲得一個迭代器的對象。因此,可迭代對象均可以經過調用內建的 iter() 方法返回一個迭代器。python

可迭代器對象具備以下的特性:express

  • 能夠 for 循環: for i in iterable;socket

  • 能夠按 index 索引的對象,也就是定義了 getitem 方法,好比 list,str;函數

  • 定義了__iter__ 方法,能夠隨意返回;spa

  • 能夠調用 iter(obj) 的對象,而且返回一個iterator。code

  • 能夠經過isinstance(obj, collections.Iterable) 來判斷對象是否爲可迭代對象。協程

迭代器對象(Iterator)

傳送門之迭代器實現原理htm

首先明確它是一個帶狀態的對象。對象

Python的for循環本質上就是經過不斷調用next()函數實現的,舉個栗子,下面的代碼

x = [1, 2, 3] for elem in x:
     ...

實際上執行時是

clipboard.png

生成器(generator)

傳送門生成器解析
傳送門之協程解密

生成器實際上是一種特殊的迭代器,不過這種迭代器更加優雅。它不須要再像上面的類同樣寫__iter__()和__next__()方法了,只須要一個yiled關鍵字。

Python對協程的支持是經過generator實現的。

生成器表達式(generator expression)

生成器表達式是列表推倒式的生成器版本,看起來像列表推導式,可是它返回的是一個生成器對象而不是列表對象。

>>> a = (x*x for x in range(10))
>>> a
<generator object <genexpr> at 0x401f08>
>>> sum(a)
285

總結

  • 容器是一系列元素的集合,str、list、set、dict、file、sockets對象均可以看做是容器,容器均可以被迭代(用在for,while等語句中),所以他們被稱爲可迭代對象。

  • 可迭代對象實現了__iter__方法,該方法返回一個迭代器對象。

  • 迭代器持有一個內部狀態的字段,用於記錄下次迭代返回值,它實現了__next__和__iter__方法,迭代器不會一次性把全部元素加載到內存,而是須要的時候才生成返回結果。

  • 生成器是一種特殊的迭代器,它的返回值不是經過return而是用yield。

相關文章
相關標籤/搜索