yield
帶有 yield 的函數在 Python 中被稱之為 generator(生成器),生成器(generator)能夠迭代的關鍵是它有一個next()方法,工作原理就是通過重復調用next()方法,直到捕獲一個異常。
生成器與迭代器會在另一篇文章介紹
yield 是一個類似 return的關鍵字,迭代一次遇到yield時就返回yield后面的值。重點是:下一次迭代時,從上一次迭代遇到的yield后面的代碼開始執行。
簡要理解:yield就是 return 返回一個值,并且記住這個返回的位置,下次迭代就從這個位置后開始。
首先先舉例了解下yield的用法
def myyield(): print ( ' start program ' ) while True: res = yield ' yes ' print ( ' resprint: ' ,res) test =myyield()
運行這段代碼會怎么樣呢?
C:\Users\11573\AppData\Local\Programs\Python\Python36\python.exe D:/pythonwork/socket/
test.py
Process finished with exit code 0
奇怪,竟然什么都沒有打印,按理說至少會打印一個?start program 才對,但是運行過后什么都沒有,這是為什么呢?
next()
程序開始執行以后,因為myyield函數中有yield關鍵字,所以myyield函數并不會真的執行,而是先得到一個生成器test(相當于一個對象),直到我們調用next方法,myyield函數正式開始執行,先執行myyield函數中的print方法,然后進入while循環
我們修改下代碼
def myyield(): print ( ' starting program ' ) while True: res = yield ' yes ' print ( ' resprint: ' ,res) test = myyield() print (next(test))
可以看到結果如下:
C:\Users\11573\AppData\Local\Programs\Python\Python36\python.exe D:/pythonwork/socket/
test.py
starting program
yes
有兩行輸出 但是我們發現并沒有執行??
print('resprint:'
,res)
這行代碼,這是因為程序遇到yield關鍵字,然后把yield想像成return,return了一個yes之后,程序停止,并沒有執行賦值給res操作,此時next(g)語句執行完成,所以輸出的前兩行
那么我們再修改下代碼:
def myyield(): print ( ' starting program ' ) while True: res = yield ' yes ' print ( ' resprint: ' ,res) test = myyield() print (next(test)) print ( ' // ' *20 ) print (next(test))
可以看到輸出如下:
C:\Users\11573\AppData\Local\Programs\Python\Python36\python.exe D:/pythonwork/socket/ test.py starting program yes //////////////////////////////////////// resprint: None yes
除了我們用作標記的 ‘////////////////////////////////////////‘ 外 多了兩行輸入
我們來看下這兩行輸出分別來自什么語句
首先輸出resprint: None 這是因為上次程序中斷在yield語句處 這次執行則直接從上次斷點繼續執行,而上次直接返回值,所以賦值為None 因此第一行輸出resprint: None
第二行輸出 yes 這是因為程序在while True循環中再次運行到了yield,因此又停止運行
因此通過這個簡單的程序我們可以大概知道yield的用法了,帶yield的函數是一個生成器,而不是一個函數了,這個生成器有一個函數就是next函數,next就相當于“下一步”生成哪個數,這一次的next開始的地方是接著上一次的next停止的地方繼續執行。
send()
yield還有一個send()函數,那么send函數的作用是什么呢?我們可以舉例子來看一下send()的作用
我們在上面代碼的基礎上增加幾行代碼:
def myyield(): print ( ' starting program ' ) while True: res = yield ' yes ' print ( ' resprint: ' ,res) test = myyield() print (next(test)) print ( ' // ' *20 ) print (next(test)) print ( ' // ' *20 ) print (test.send( ' sending yes ' ))
看下輸出:
C:\Users\11573\AppData\Local\Programs\Python\Python36\python.exe D:/pythonwork/socket/ test.py starting program yes //////////////////////////////////////// resprint: None yes //////////////////////////////////////// resprint: sending yes yes
奇怪,之前的resprint都是None,這次卻有了賦值,
這是因為,send是發送一個參數給res的,在next函數return的時候,并沒有把 'yes' 賦值給res,下次執行的時候只好繼續執行賦值操作,只好賦值為None了,而如果用send的話,開始執行的時候,先接著上
一次(return yes之后)執行,先把 'sending yes' 賦值給了res,然后執行next的作用,遇見下一回的yield,return出結果后結束。send方法中包含next()方法,所以程序會繼續向下運行執行print方法,然后再次
進入while循環程序執行再次遇到yield關鍵字,yield會返回后面的值后,程序再次暫停,直到再次調用next方法或send方法。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
