一. 剖析一下生成器對象
先看一個簡單的例子真仲,我們創(chuàng)建一個生成器函數(shù),然后生成一個生成器對象
表示G是一個生成器對象,我們來剖析一下,里面到底有什么
print dir(G)
>>['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__','close', 'gi_code', 'gi_frame', 'gi_running',
'next', 'send', 'throw']
大家注意看有4個很特殊的函數(shù)close(),next(),send(),throw(),next()函數(shù)前面兩篇文章講過了,我就不再說.今天我們就重點來說說send(),throw(),close()函數(shù)
二. 什么是協(xié)程
Python的協(xié)程有點類似線程戳护,可以認(rèn)為協(xié)程是一種用戶級的輕量級線程或者微線程,可以運(yùn)行多個函數(shù)瀑焦,讓這幾個函數(shù)看起來好像是在同一時間運(yùn)行,但是比線程有一些優(yōu)點,比如不用大量占內(nèi)存腌且,開銷小,也不用考慮線程安全.(關(guān)于什么是線程后面文章會講)
1.send()函數(shù)
send()用于傳遞參數(shù)蝠猬,實現(xiàn)與生成器的交互,當(dāng)程序運(yùn)行到receive=yield的時候 就會被掛起,等待生成器調(diào)用send方法,這個時候外部調(diào)用send函數(shù)切蟋,發(fā)送數(shù)據(jù)變量進(jìn)來,數(shù)據(jù)變量就會傳遞到received
示例代碼:
a).echo函數(shù)里面一個死循環(huán)榆芦,里面有一行關(guān)鍵的代碼,receive=yield 這個就是send函數(shù)從外部發(fā)送過來的入口.
b).外部函數(shù)一開始要生成一個生成器對象也就是Echo=echo()
c).然后很關(guān)鍵的一步就是next(Echo),一定要調(diào)用一次next函數(shù)柄粹,讓生成器推進(jìn)到第一條yield表達(dá)式那邊
d).接下來我們就可以把yield操作和send操作結(jié)合起來,可以獲取外界所輸入的數(shù)據(jù)匆绣,然后用一套流程去進(jìn)行處理
2.throw()函數(shù)
throw主要是向生成器發(fā)送一個異常驻右,可以結(jié)束系統(tǒng)定義的異常(當(dāng)然包括自定義的異常)
示例代碼:
a).創(chuàng)建生成器對象G
b),執(zhí)行next(G)并打印結(jié)果,我們會得到第一個yield里緩存的結(jié)果'First'崎淳,并且停留在yield 'Second'之前
c).拋出一個異常類ValueError(注意ValueError是類不是字符串)堪夭,當(dāng)生成器收到異常直接跳過 yield 'Second'進(jìn)入except部分,打印出'Catch the TypeError'
d).執(zhí)行next(G)并打印結(jié)果,我們會回到while頭部拣凹,并且消耗掉第一個yield 'Frist',執(zhí)行yield 'Second'
3.close()函數(shù)
close用于停止生成器,如果停止之后再調(diào)用next,就會引發(fā)StopIteration錯誤
示例代碼:
當(dāng)生成器對象Echo調(diào)用完close()之后森爽,再調(diào)用send('123')就會拋出一個異常StopIteration,然后被我們捕捉到了
三. 實戰(zhàn)應(yīng)用-迷你聊天機(jī)器人
講了這么多嚣镜,大家是不是有點暈爬迟,
生成器本身就是Python里面最復(fù)雜的概念之一,有同學(xué)問難道還有之二(是的,就是裝飾器)
,我們用協(xié)程寫一個小的聊天機(jī)器人吧~~
1).創(chuàng)建一個聊天機(jī)器人生成器函數(shù),可以認(rèn)為是后臺的一個線程函數(shù)
2).前臺不斷的獲取用戶的輸入,然后利用協(xié)程發(fā)送給后臺處理
看一下運(yùn)行的效果
需要源碼的同學(xué)后臺給我聯(lián)系