深入淺析Python中的yield關鍵字,pythonyield
前言
python中有一個非常有用的文法叫做產生器,所利用到的關鍵字就是yield。有效利用產生器這個工具可以有效地節約系統資源,避免不必要的記憶體佔用。
一段代碼
def fun():for i in range(20): x=yield i print('good',x)if __name__ == '__main__':a=fun()a.__next__()x=a.send(5)print(x)
這段代碼很短,但是詮釋了yield關鍵字的核心用法,即逐個產生。在這裡擷取了兩個產生器產生的值,即0和1。分別由next函數和send()函數獲得,這兩個函數的區別我們後面會詳細闡述。
關於__next__函數,這裡先說明一下,我們可以利用__next__()這個函數持續擷取符合fun函數規則的數,直到19結束。這段代碼如下所示:
def fun():for i in range(20): x=yield iif __name__ == '__main__':for x in fun(): print(x)
這段代碼的效果和下面這段代碼是完全相同的
if __name__ == '__main__':for i in range(20): x=yield i
for..in調用產生器算是產生器的基礎用法,不過只會用for..in意義是不大的。產生器中最重要的函數是sent和__next__這兩個函數,下面就針對這兩個函數進行詳細的闡述。
sent函數
這裡特彆強調了sent函數,因為sent函數沒有那麼直觀。__next__函數很好理解,就是從上一個終止點開始,到下一個yield結束,傳回值就是yield運算式的值。
例如在初始的那段代碼裡:
def fun():for i in range(20): x=yield i print('good',x)
第一次調用__next__函數的時候,我們從fun的起點開始,然後在yield處結束,需要注意的是,指派陳述式不會調用,此處yield i和含義和return差不多。
但是第二次調用__next__函數的時候,就會直接從上一個yield的結束處開始,也就是先執行指派陳述式,然後輸出字串,進入下一個迴圈,直到下一個yield或者產生器結束
再次看初始的那段代碼,可以發現第二次調用的時候沒有選擇使用__next__函數,而是使用了一個sent()函數。這裡就需要注意,sent()函數的用法和__next__函數不太一樣。sent()函數只能從yield之後開始,到下一個yield結束。這也就意味著第一次調用必須使用__next__函數。
sent()函數最重要的作用在於它可以給yield對應的指派陳述式賦值,比如上面那一段代碼中的
x=yield i
如果調用__next()__函數,那麼x=None。但是如果調用sent(5),那麼x=5。除了上述將的兩個特徵以外,sent和next並沒有什麼區別,sent函數也會返回yield運算式對應的值
next函數調用次可能有限
需要特別注意的是,儘管是產生器。但是next函數的調用次數可能是有限的。比如下面這段代碼
def fun():for i in range(20): x=yield i print('good',x)if __name__ == '__main__':a=fun()for i in range(30): x=a.__next__() print(x)
產生器裡的函數只迴圈了20次,但是next函數卻調用了30次,這時候就會觸發StopIteration異常。
總結
以上所述是小編給大家介紹的Python中的yield關鍵字,希望對大家有所協助,如果大家有任何疑問請給我留言,小編會及時回複大家的。在此也非常感謝大家對幫客之家網站的支援!