生活随笔
收集整理的這篇文章主要介紹了
[转]python yield
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
任何使用yield的函數都稱之為生成器,如:
Python代碼??
def?count(n):??????while?n?>?0:??????????yield?n???????????n?-=?1?? ?
另外一種說法:生成器就是一個返回迭代器的函數,與普通函數的區別是生成器包含yield語句,更簡單點理解生成器就是一個迭代器。
使用yield,可以讓函數生成一個序列,該函數返回的對象類型是"generator",通過該對象連續調用next()方法返回序列值。
Python代碼??
c?=?count(5)??c.next()??>>>?5??c.next()??>>>4?? ?
生成器函數只有在調用next()方法的時候才開始執行函數里面的語句,比如:
Python代碼??
def?count(n):??????print?"cunting"??????while?n?>?0:??????????yield?n???????????n?-=?1?? ?
在調用count函數時:c=count(5),并不會打印"counting"只有等到調用c.next()時才真正執行里面的語句。每次調用next()方法時,count函數會運行到語句yield n處為止,next()的返回值就是生成值n,再次調用next()方法時,函數繼續執行yield之后的語句(熟悉Java的朋友肯定知道Thread.yield()方法,作用是暫停當前線程的運行,讓其他線程執行),如:
Python代碼??
def?count(n):??????print?"cunting"??????while?n?>?0:??????????print?'before?yield'??????????yield?n???????????n?-=?1??????????print?'after?yield'?? ?
上述代碼在第一次調用next方法時,并不會打印"after yield"。如果一直調用next方法,當執行到沒有可迭代的值后,程序就會報錯:
Traceback (most recent call last): File "", line 1, in StopIteration
所以一般不會手動的調用next方法,而使用for循環:
Python代碼??
for?i?in?count(5):??????print?i,?? ?
實例: 用yield生成器模擬Linux中命令:tail -f | grep python?用于查找監控日志文件中出現有python字樣的行。
Python代碼??
import?time??def?tail(f):??????f.seek(0,2)????while?True:??????????line?=?f.readline()??????????if?not?line:??????????????time.sleep(0.1)??????????????continue??????????yield?line????def?grep(lines,searchtext):??????for?line?in?lines:??????????if?searchtext?in?line:??????????????yield?line?? ?
調用:
Python代碼??
flog?=?tail(open('warn.log'))??pylines?=?grep(flog,'python')??for?line?in?pylines:??????print?line,?? ?
用yield實現斐波那契數列:
Python代碼??
def?fibonacci():??????a=b=1??????yield?a??????yield?b??????while?True:??????????a,b?=?b,a+b??????????yield?b?? ?
調用:
Python代碼??
for?num?in?fibonacci():??????if?num?>?100:??????????break??????print?num,?? ?
yield中return的作用:
作為生成器,因為每次迭代就會返回一個值,所以不能顯示的在生成器函數中return 某個值,包括None值也不行,否則會拋出“SyntaxError”的異常,但是在函數中可以出現單獨的return,表示結束該語句。
通過固定長度的緩沖區不斷讀文件,防止一次性讀取出現內存溢出的例子:
Python代碼??
def?read_file(path):??????size?=?1024??????with?open(path,'r')?as?f:??????????while?True:??????????????block?=?f.read(SIZE)??????????????if?block:??????????????????yield?block??????????????else:??????????????????return?? ?
如果是在函數中return 具體某個值,就直接拋異常了
Python代碼??
>>>?def?test_return():??...??????yield?4??...??????return?0??...????File?"<stdin>",?line?3??SyntaxError:?'return'?with?argument?inside?generator?? ?原文地址:http://liuzhijun.iteye.com/blog/1852369#comments
轉載于:https://www.cnblogs.com/frankcoder/p/5121734.html
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的[转]python yield的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。