可能當(dāng)你一開始學(xué)python的時(shí)候皿伺,就不可避免的和迭代器接觸了。
迭代器
一開始盒粮,我大概有個(gè)模糊的概念鸵鸥,比如在for循環(huán)中,其實(shí)隱藏了大量的迭代器細(xì)節(jié)丹皱,我們看到的不過是在迭代器協(xié)議下可遍歷對(duì)象的不斷迭代而已妒穴。正是因?yàn)榈鲄f(xié)議的存在,在python語(yǔ)言中for也可以對(duì)文件系統(tǒng)等進(jìn)行遍歷种呐,因?yàn)橹灰憔哂小?strong>next”和“iter”屬性宰翅,python都可以使用迭代器協(xié)議來訪問對(duì)象。
但是如果你自己想寫迭代器的話需要注意什么呢爽室?
class fib():
def __init__(self):
self.forward = 0
self.next = 1
def __iter__(self):
return self
def __next__(self):
value = self.forward
self.forward += self.next
self.next = value
return value
f = fib()
for i in f:
if i > 10:
break
else:
print(i)
這是典型的斐波那契數(shù)列實(shí)現(xiàn)的迭代器寫法汁讼,可以看出我們?cè)谑褂胒or循環(huán)對(duì)他進(jìn)行遍歷的時(shí)候,其實(shí)是調(diào)用“iter”獲得迭代器阔墩,再調(diào)用“next”獲取元素嘿架。
生成器
生成器時(shí)一種特殊的迭代器,生成器自動(dòng)實(shí)現(xiàn)了迭代器協(xié)議啸箫,不需要手動(dòng)的實(shí)現(xiàn)“iter”和“next”方法耸彪。
生成器通常有兩種形式,生成器函數(shù)和生成器表達(dá)式:
def squre(i):
for a in range(i):
# a = i*i
yield a ** 2
for item in squre(5):
print (item)
上述為生成器函數(shù)忘苛,同樣可以用迭代器方式完成蝉娜,但是不可避免的使用到了列表等結(jié)構(gòu)讓代碼更加復(fù)雜唱较。
下面所示的生成器表達(dá)式的方式,也是很常用的特性召川。
>>> squares = (x**2 for x in range(5))
>>> squares
<generator object <genexpr> at 0x7fa8c8369bf8>
這種延遲計(jì)算的特性對(duì)于大數(shù)據(jù)的處理具有不錯(cuò)的效益南缓,當(dāng)然還有pythonic的性質(zhì),這在前文我們已經(jīng)提到過了荧呐。
閉包
最后講一下閉包汉形。
前面已經(jīng)提過了,python的返回值是可以返回一個(gè)函數(shù)的倍阐,那么閉包其實(shí)就是函數(shù)的內(nèi)部函數(shù)概疆,同時(shí)在該內(nèi)部函數(shù)中引用了外部定義的變量等。舉個(gè)例子:
def a(x):
def b(y):
return x+y
return b
a = a(1)
print("func:",a)
print("result:",a(1))
輸出是:
func <function a.<locals>.b at 0x00000213A67DFF28>
result 2
閉包作為裝飾器的基礎(chǔ)峰搪,還是很有用的岔冀。