生成器(generator)
1.生成器簡介
首先請確信,生成器就是一種迭代器。生成器擁有next方法并且行為與迭代器完全相同,這意味著生成器也可以用于Python的for循環中。另外,對于生成器的特殊語法支持使得編寫一個生成器比自定義一個常規的迭代器要簡單不少,所以生成器也是最常用到的特性之一。
從Python2.5開始,[PEP342:通過增強生成器實現協同程序]的實現為生成器加入了更多的特性,這意味著生成器還可以完成更多的工作。這部分我們會在稍后的部分介紹。
2.生成器函數
2.1.使用生成器函數定義生成器
如何獲取一個生成器?首先來看一小段代碼:
>>>defget_0_1_2():
...yield0
...yield1
...yield2
...
>>>get_0_1_2
我們定義了一個函數get_0_1_2,并且可以查看到這確實是函數類型。但與一般的函數不同的是,get_0_1_2的函數體內使用了關鍵字yield,這使得get_0_1_2成為了一個生成器函數。生成器函數的特性如下:
調用生成器函數將返回一個生成器;
>>>generator=get_0_1_2()
>>>generator
第一次調用生成器的next方法時,生成器才開始執行生成器函數(而不是構建生成器時),直到遇到yield時暫停執行(掛起),并且yield的參數將作為此次next方法的返回值;
>>>generator.next()
之后每次調用生成器的next方法,生成器將從上次暫停執行的位置恢復執行生成器函數,直到再次遇到yield時暫停,并且同樣的,yield的參數將作為next方法的返回值;
>>>generator.next()
>>>generator.next()
如果當調用next方法時生成器函數結束(遇到空的return語句或是到達函數體末尾),則這次next方法的調用將拋出StopIteration異常(即for循環的終止條件);
>>>generator.next()
Traceback(mostrecentcalllast):
File"",line1,in
StopIteration
生成器函數在每次暫停執行時,函數體內的所有變量都將被封存(freeze)在生成器中,并將在恢復執行時還原,并且類似于閉包,即使是同一個生成器函數返回的生成器,封存的變量也是互相獨立的。
我們的小例子中并沒有用到變量,所以這里另外定義一個生成器來展示這個特點:
>>>deffibonacci():
...a=b=1
...yielda
...yieldb
...whileTrue:
...a,b=b,a+b
...yieldb
...
>>>fornuminfibonacci():
...ifnum>100:break
...printnum,
...
1123581321345589
看到whileTrue可別太吃驚,因為生成器可以掛起,所以是延遲計算的,無限循環并沒有關系。這個例子中我們定義了一個生成器用于獲取斐波那契數列。
以上內容為大家介紹了Python函數式編程指南之生成器,希望對大家有所幫助,如果想要了解更多Python相關知識,請關注IT培訓機構:千鋒教育。