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
語句,就不再是一個函數了,而是變成了一個具有迭代功能的生成器。所以你無法用執行語句的方法呼叫他,必須用next
和send
函式進行呼叫。然後涉及到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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。