1. 程式人生 > >return 和yield的區別

return 和yield的區別

 

詳情請檢視:https://www.jianshu.com/p/a3383b144eb6

yield和return

對於新手來說,這兩個是容易讓人混淆的地方,這裡再梳理一遍


 

解釋一

就像打電玩一樣,你蓄力發大招的時候,如果執行了return,就直接把大招發出去了,蓄力結束

如果執行了yield,就相當於返回一個生成器物件,每呼叫一次next(),就發一個大招


 

解釋二

return 是函式返回值,當執行到return,後續的邏輯程式碼不在執行

yield是建立迭代器,可以用for來遍歷,有點事件觸發的意思


 

解釋三

return是用來返回具體的某個值,yield一般與迴圈一起用,相當於生成了一個容器(常見的就是字典),然後在這個容器裡面存放了每次迴圈以後的值,並且就在那放著,不輸出,不返回,等你下次需要他的時候直接取出來用(呼叫)就行


 

解釋四

換個角度來說,從控制權來說。函式裡遇到return時,控制權交給主執行緒,然後沒這個函式什麼事了。如果遇到yield,控制權只是暫時交給主執行緒,函式繼續在那等著。另外,函式裡出現yield就自動變成生成器。


 

解釋五

yield在寫爬蟲的時候用來迴圈獲取資料挺好用的
return:
做一件事,做到A節點的時候,碰到 ‘’return 拿出成果‘’,那你就把成果拿出來,並且停止之後的事情。

yield:
做一件事,做到A節點的時候,碰到 ‘’yield 拿出成果‘’,那你就把成果拿出來,拿出來之後,接著做後面的事情。


 

解釋六

y和r所在的函式是兩個性質不同的函式。你可以理解為只要一個函式包含yield語句,就不再是一個函數了,而是變成了一個具有迭代功能的生成器。所以你無法用執行語句的方法呼叫他,必須用nextsend函式進行呼叫。然後涉及到send傳遞的引數值就是yield表示式的值。也就是比如你執行了send(5來呼叫yield函式,此時yield函式中有個表示式a=yield 3,如果你此時列印a的值,a的值為5。還有就是yield返回值就是send

語句的值。比如上面那個例子,你列印send(5),那麼它的值是3。

新手難以理解yield函式就是因為把生成器和普通的函式弄混了。可以說一個yeild函式除了長得像函式,其他的地方几乎沒有函式的影子。他只是起了一個生成器的作用,多用於非同步或者遞迴。


 

程式碼示例

#encoding:UTF-8  
def yield_test(n):  
    for i in range(n):  
        yield call(i)     # 它會立即把call(i)輸出,成果拿出來後才會進行下一步,所以 i, ',' 會先執行
        print("i=",i)     # 後執行
    #做一些其它的事情      
    print("do something.")        #  待執行,最後才執行一遍
    print("end.")  
  
def call(i):  
    return i*2  
  
#使用for迴圈  
for i in yield_test(5):  
    print(i,",")   # 這裡的 i 是 call(i)
>>>        # 輸出的結果
0 ,  
i= 0  
2 ,  
i= 1  
4 ,  
i= 2  
6 ,  
i= 3  
8 ,  
i= 4  
do something.  
end.  
>>> 

理解的關鍵在於:下次迭代時,程式碼從yield的下一跳語句開始執行。



舉個簡單的例子,定義一個generator,依次返回數字1,3,5:

 

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)

呼叫該generator時,首先要生成一個generator物件,然後用next()函式不斷獲得下一個返回值:

>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

可以看到,odd不是普通函式,而是generator,在執行過程中,遇到yield就中斷,下次又繼續執行。執行3次yield後,已經沒有yield可以執行了,所以,第4次呼叫next(o)就報錯。



作者:時間之友
連結:https://www.jianshu.com/p/a3383b144eb6
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。