從文法上來看,協程和生成器類似,都是在定義體中包含yield關鍵字的函數
但在
協程中yield關鍵字通常出現在表達式的右邊:
- 可以産出值n(y = yield n)
- 也可以不産出值(y = yield),或者說是産出值為None
通過
next(coroutine)函數
激活協程:- 調用next(),傳回 yield右邊的可有可無的值或者函數值( 一般不需要next産出值,即, yield後無值,= yield ), 暫停
是通過
send(datum=None)的方式把資料提供給協程使用:
- send(n)函數的傳回值為 yield右邊的值或者函數值
- 等号左邊的變量接受send(n)函數傳來的值
- 可以了解為 函數next()和函數send(n)都 會執行yield右邊的 值或者函數值,
- 但是 , send(n)函數執行完 不會暫停 ,同時send(n)函數的 參數n會指派給等号左邊的變量
def

這裡的對應于
send(n)的操作 y
= yield實際上是
按2步進行的- 第1步yield 接受send(n)函數傳來的參數值 , 并指派 給 等号=左邊 的變量,即y=n
- 第2步執行 yield後面的表達式或者函數并傳回值
為了檢視協程在運作過程中的四個狀态,我們引入
from inspect import getgeneratorstate- GEN_CREATED :生成器建立完成,等待執行,可以了解為線程的就緒狀态
- GEN_RUNNING :一般看不到,可了解為線程的執行狀态
- GEN_SUSPENDED :在yield表達式處暫停,可了解為線程的阻塞狀态
- GEN_CLOSED :執行結束,可了解為線程的死亡狀态
擷取協程的傳回值
- 從異常屬性中擷取:協程結束時會跟生成器一樣抛出StopIteration的異常, 傳回值 就在異常對象的 value 屬性中
- yield from内部會自動捕獲 後面 協程StopIteration異常,并把異常對象的value屬性變成yield from的傳回值
- yield from 的主要功能就是打開雙向通道,最外層的調用方調用 子生成器 ,同時子生成器也可使用yield from調用另一個子生成器,一直嵌套調用 直到遇到yield 表達式結束
- send(n) 發送的值n通過yield from直接傳遞給了 最内層的子生成器 ,并在yield from處等待子生成器的傳回
叢異常中擷取協程傳回值(1)
叢異常中擷取協程傳回值(2)
異步IO(asyncio)
- Python 3.4版本引入 異步IO的标準庫asyncio, 使用事件循環 驅動協程 實作并發。
- 在asyncio庫中, 用asyncio.coroutine裝飾 , 用yield from來驅動協程
- Python 3.5版本中 用async代替了 asyncio.coroutine,用 await代替了 yield from
下面展示了Python 3.4中标準庫
asyncio中協程(coroutine)的應用
import threading importasyncio
@asyncio.coroutine
def hello():
print('Hello world! (%s)' % threading.currentThread())
yield fromasyncio.sleep(1)
print('Hello again! (%s)' % threading.currentThread())
loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
asynciowww.liaoxuefeng.com