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

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