python 關鍵字yield學習

關鍵字yield學習

  • 生成器與yield

  • 協成與yield

實例

  • python中有一個非常有用的語法叫做生成器,所利用到的關鍵字就是yield。有效利用生成器這個工具可以有效地節約系統資源,避免不必要的內存佔用。
  • 只要出現了yield表達式(Yield expression),那麼事實上定義的是一個generator function。
    生成器
def fun():
    print("*start*"*2)
    for i in range(20):
        x=yield i
        print('good',x)

if __name__ == '__main__':
    a=fun()
    
    print(a.__next__())
    print(a.__next__())

輸出結果

*start**start*
0
good None
1

流程解釋

  1. 程序開始執行以後,因爲fun函數中有yield關鍵字,所以fun函數並不會真的執行,而是先得到一個生成器g(相當於一個對象)
  2. 直到調用next方法,fun函數正式開始執行,先執行fun函數中的print方法,然後進入for循環
  3. 程序遇到yield關鍵字,然後把yield想想成return,return了一個i之後,程序停止,並沒有執行賦值給x操作,此時a.next()語句執行完成,所以輸出的前兩行
  4. 又開始執行下面的print(a.next()),這個時候和上面那個差不多,不過不同的是,這個時候是從剛纔那個next程序停止的地方開始執行的,也就是要執行x的賦值操作,這時候要注意,這個時候賦值操作的右邊是沒有值的(因爲剛纔那個是return出去了,並沒有給賦值操作的左邊傳參數),所以這個時候x賦值是None,所以接着下面的輸出就是x:None,

協程

  • 從句法上看,協程與生成器類似,都是定義體中包含 yield 關鍵字的函數。可是,在協程中, yield 通常出現在表達式的右邊(例如, datum = yield),可以產出值,也可以不產出 —— 如果 yield 關鍵字後面沒有表達式,那麼生成器產出 None。
  • 協程可能會從調用方接收數據,不過調用方把數據提供給協程使用的是 .send(datum) 方法,而不是next(…) 函數。
def fun():
    print("*start*"*2)
    for i in range(20):
        x=yield i
        print('good',x)

if __name__ == '__main__':
    a=fun()
    
    print(a.__next__())
    print(a.send(5))
    print(a.__next__())
    a.send(6)

輸出結果

*start**start*
0
good 5
1
good None
2
good 6

流程解釋

  1. 先執行a.next(),x爲none
  2. 程序執行a.send(5),a.send(5)是發送一個參數5給x, x爲5.程序會從yield關鍵字那一行繼續向下運行,所以程序會繼續向下運行執行print方法,打印了good 5。
  3. 由於send方法中包含next()方法,然後執行next的作用,再次進入for循環,遇見下一回的yield,打印了1
  4. 遇到第二個a.next()時,接着上一個next()方法停止的地方開始執行也就是yield處,由於沒有send所以x爲none,先打印2,再打印good none
  5. 同理再次執行send程序執行再次遇到yield關鍵字,yield會返回後面的值後,程序再次暫停,直到再次調用next方法或send方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章