python菜鳥學習Day12 yield

2021-10-01 17:56:16 字數 3595 閱讀 6648

在python中,帶yield的函式稱為生成器(generator),python對協程的支援也是通過生成器實現的。

yield

首先將yield當成乙個斷點標記,中斷,return 。當程式執行到yield處,返回yield後邊的變數,中斷。其他程式獲取這個變數,呼叫生成器的next()函式,程式又回到生成器,接著向下執行。

乙個帶有 yield 的函式就是乙個 generator,它和普通函式不同,生成乙個 generator 看起來像函式呼叫,但不會執行任何函式**,直到對其呼叫 next()(在 for 迴圈中會自動呼叫 next())才開始執行。雖然執行流程仍按函式的流程執行,但每執行到乙個 yield 語句就會中斷,並返回乙個迭代值,下次執行時從 yield 的下乙個語句繼續執行。看起來就好像乙個函式在正常執行的過程中被 yield 中斷了數次,每次中斷都會通過 yield 返回當前的迭代值。

def

foo():

print

("starting..."

)while

true

: res =

yield

4print

("res:"

,res)

g = foo(

)print

(next

(g))

print

("*"*20

)print

(next

(g))

執行結果

starting...

4******

****

****

****

**res:

none

4

1首先foo函式含有yield,是乙個生成器,g = foo(),並不執行foo()函式,而是返回乙個迭代器物件賦值給g。

2 呼叫迭代器物件g的next()方法,foo函式開始執行,列印"starting…",進入while迴圈,執行到yield,中斷,return後邊的變數4,程式跳轉回到print(next(g))。即print(yield返回的變數4)。

3 順序執行print("*"*20)。

4 再次呼叫迭代器物件g的next()方法,程式跳轉到上次next結束的地方,即res賦值操作,因為變數4被return出去了,所以res賦值為空。執行print(「res:」,res),即列印res: none,繼續迴圈到yield,再次中斷,return 後邊的變數4,然後跳轉到print(next(g)),即列印4。

生成器有乙個重要的方法next(),呼叫next(),程式從上次next()停止的地方開始執行,直至遇到yield,返回後面的變數,此步停止。

send例子

send(value)

迭代器物件的send方法,傳送乙個值value給生成器,並返回下乙個yield的值(也就行呼叫next()方法)。

def

foo():

print

("starting..."

)while

true

: res =

yield

4print

("res:"

,res)

g = foo(

)print

(next

(g))

print

("*"*20

)print

(g.send(7)

)

結果

starting...

4******

****

****

****

**res:

74

最後一步:g.send(7),回到上次yield結束的地方,即res賦值操作,即把send的值7賦值給res,繼續執行,即列印res,然後執行到yield,返回yield後面的變數4,中斷跳出。回到print(g.send(7)),即列印pirnt(4).

使用生成器可以節省記憶體空間,比如for i in range(1000),則會生成乙個list儲存1000個元素,而for i in xrange(1000),xrange(1000)就是乙個生成器,每次yield 乙個元素。

讀取文字,如果直接讀取,會將文字內容全部載入到記憶體中,占用大量記憶體,而生成器則每次yield固定大小block_size 的文字塊到記憶體。

def

read_file

(fpath)

: block_size =

1024

with

open

(fpath,

'rb'

)as f:

while

true

: block = f.read(block_size)

if block:

yield block

else

:return

send函式和for迴圈都會自動呼叫next()函式。當函式執行結束時,generator 自動丟擲 stopiteration 異常,表示迭代完成。在 for 迴圈裡,無需處理 stopiteration 異常,迴圈會正常結束。

python對協程的支援是通過generator實現的。

在generator中,我們不但可以通過for迴圈來迭代,還可以不斷呼叫next()函式獲取由yield語句返回的下乙個值。但是python的yield不但可以返回乙個值,它還可以接收呼叫者發出的引數。

生產者–消費者模型

def

consumer()

: r =

''while

true

: n =

yield r

ifnot n:

return

print

('[consumer] consuming %s...'

% n)

r ='200 ok'

defproduce

(c):

c.send(

none

)#啟動生成器 想當與next(c)

n =0while n <5:

n = n +

1print

('[producer] producing %s...'

% n)

r = c.send(n)

print

('[producer] consumer return: %s'

% r)

c.close(

)c = consumer(

)produce(c)

1 c = consumer(),返回乙個迭代器物件。並不執行consumer,在呼叫next方法才會執行。

2 produce(c )中,c.send(none) 啟動生成器。produce一旦生產了東西,通過 c.send(n)切換到consumer,consumer通過yield拿到東西,經過處理後,有經過下乙個yield返回。pruduce拿到處理的結果,繼續生產下乙個東西。produce決定不生產,通過c.close()關閉consumer,整個過程結束.

python菜鳥學習Day12 裝飾器,列舉類

裝飾器 decorater 當想改變函式的功能,而不改變函式本身定義的時候,就用到了裝飾器。比如,列印函式呼叫的日誌。正常來說在函式中新增print 或者呼叫log包就行。但不想改變函式本身,就需要裝飾器來完成。裝飾器是高階函式,引數是需要列印日誌的函式,返回值也是函式。from functools...

python學習 day12 模組os sys

內容 以下內容僅供個人學習使用,侵刪 usr bin env python coding utf 8 os 通過程式與作業系統做互動 import os 四個維度 重要的 1.資料夾 建立資料夾 os.mkdir,os.makedirs 刪除資料夾 os.rmdir,os.removedirs 檢視...

前端學習Day12

一 定位 1.position static absolute relative 2.position fixed 固定定位 a 參照物 瀏覽器視窗 b 不佔據空間,脫離布局流 3.讓乙個元素在瀏覽器視窗左右上下居中?第一種方法 前提 已知寬和高 position fixed left 50 top...