實(shí)例解析Python的Twisted框架中Deferred對(duì)象的用法
Deferred對(duì)象結(jié)構(gòu)
Deferred由一系列成對(duì)的回調(diào)鏈組成,每一對(duì)都包含一個(gè)用于處理成功的回調(diào)(callbacks)和一個(gè)用于處理錯(cuò)誤的回調(diào)(errbacks)。初始狀態(tài)下,deffereds將由兩個(gè)空回調(diào)鏈組成。在向其中添加回調(diào)時(shí)將總是成對(duì)添加。當(dāng)異步處理中的結(jié)果返回時(shí),Deferred將會(huì)啟動(dòng)并以添加時(shí)的順序觸發(fā)回調(diào)鏈。
用實(shí)例也許更容易說(shuō)明,首先來(lái)看看addCallback:
from twisted.internet.defer import Deferred def myCallback(result): print result d = Deferred() d.addCallback(myCallback) d.callback("Triggering callback.")
運(yùn)行它將會(huì)得到如下結(jié)果:
Triggering callback.
上例中創(chuàng)建了一個(gè)deffered并利用其addCallback方法注冊(cè)一個(gè)用于處理成功的回調(diào)。d.callback會(huì)啟動(dòng)deffered并調(diào)用callback鏈。傳入callback的參數(shù)也會(huì)被各callback鏈中的第一個(gè)函數(shù)接收到。
有addCallback,那另一個(gè)錯(cuò)誤的分支,我想也能猜測(cè)到了那就是addErrorback,同樣來(lái)看個(gè)例子:
from twisted.internet.defer import Deferred def myErrback(failure): print failure d = Deferred() d.addErrback(myErrback) d.errback(ValueError("Triggering errback."))
運(yùn)行它將會(huì)得到如下結(jié)果:
[Failure instance: Traceback (failure with no frames): <type 'exceptions.ValueError'>: Triggering errback.]
可以看出Twisted會(huì)把錯(cuò)誤封裝在Failure里。
值得注意的是,在之前提到過(guò)注冊(cè)回調(diào)總是成對(duì)的。在使用d.addCallback和d.addErrorback方法時(shí),我們看似只是添加了一個(gè)callback或一個(gè)errback。而實(shí)際上,為了完成這一級(jí)回調(diào)鏈的創(chuàng)建,這些方法還會(huì)為另一半注冊(cè)一個(gè)pass-through。要記住,回調(diào)鏈總是具有相同的長(zhǎng)度。如果要分別指定這一級(jí)回調(diào)的callback和errback??梢允褂胐.addCallbacks方法:
d = Deferred() d.addCallbacks(myCallback, myErrback) d.callback("Triggering callback.")
進(jìn)階示例
接下來(lái)就應(yīng)該來(lái)點(diǎn)更為實(shí)際的,那就是放進(jìn)Reactor。先來(lái)看一個(gè)例子:
from twisted.internet import reactor, defer class HeadlineRetriever(object): def processHeadline(self, headline): if len(headline) > 50: self.d.errback(Exception("The headline ``%s'' is too long!" % (headline,))) else: self.d.callback(headline) def _toHTML(self, result): return "<h1>%s</h1>" % (result,) def getHeadline(self, input): self.d = defer.Deferred() reactor.callLater(1, self.processHeadline, input) self.d.addCallback(self._toHTML) return self.d def printData(result): print result reactor.stop() def printError(failure): print failure reactor.stop() h = HeadlineRetriever() d = h.getHeadline("Breaking News: Twisted Takes us to the Moon!") d.addCallbacks(printData, printError) reactor.run()
上例接收一個(gè)標(biāo)題并對(duì)其進(jìn)行處理,如果標(biāo)題超長(zhǎng)會(huì)返回超長(zhǎng)的錯(cuò)誤,否則將其轉(zhuǎn)為HTML并返回。
因所給的標(biāo)題少于50個(gè)字符,故執(zhí)行以上代碼會(huì)得到如下返回:
<h1>Breaking News: Twisted Takes us to the Moon!</h1>
有一點(diǎn)值得注意的,上面用到了reactor的callLater方法,它可以用來(lái)做定時(shí)事件從而模擬一個(gè)異步的請(qǐng)求。
如果我們將標(biāo)題變得很長(zhǎng),比如說(shuō):
h = HeadlineRetriever() d = h.getHeadline("1234567890"*6) d.addCallbacks(printData, printError)
那結(jié)果是可以遇見(jiàn)的:
[Failure instance: Traceback (failure with no frames): <type 'exceptions.Exception'>: The headline ``123456789012345678901234567890123456789012345678901234567890'' is too long!]

Deferreds中的關(guān)鍵之處
1. Deferreds將會(huì)在調(diào)用其callback或errback時(shí)被觸發(fā);
2. Deferreds僅能被觸發(fā)一次!如果嘗試多次觸發(fā)將會(huì)導(dǎo)致AlreadyCalledError異常;
3. 第N級(jí)callback或errback中的Exceptions將會(huì)傳入第N+1級(jí)的errback中;如果沒(méi)有errback,則會(huì)拋出Unhandled Error。如果第N級(jí)callback或errback中沒(méi)有拋出Exception或返回Failure對(duì)象,那接下來(lái)將會(huì)由第N+1級(jí)中的callback進(jìn)行處理;
4. callback中返回的結(jié)果將會(huì)傳入下一級(jí)callback,并作為其第一個(gè)參數(shù);
5. 如果傳入errback的錯(cuò)誤不是一個(gè)Failure對(duì)象,那將會(huì)被自動(dòng)包裝一次。
- python如何通過(guò)twisted搭建socket服務(wù)
- Python3.6中Twisted模塊安裝的問(wèn)題與解決
- python安裝twisted的問(wèn)題解析
- python如何通過(guò)twisted實(shí)現(xiàn)數(shù)據(jù)庫(kù)異步插入
- python基于twisted框架編寫(xiě)簡(jiǎn)單聊天室
- python 編程之twisted詳解及簡(jiǎn)單實(shí)例
- Python 基于Twisted框架的文件夾網(wǎng)絡(luò)傳輸源碼
- 剖析Python的Twisted框架的核心特性
- 詳解Python的Twisted框架中reactor事件管理器的用法
- 使用Python的Twisted框架編寫(xiě)非阻塞程序的代碼示例
- Python的Twisted框架中使用Deferred對(duì)象來(lái)管理回調(diào)函數(shù)
- 使用Python的Twisted框架構(gòu)建非阻塞下載程序的實(shí)例教程
- Python的Twisted框架上手前所必須了解的異步編程思想
- 使用Python的Treq on Twisted來(lái)進(jìn)行HTTP壓力測(cè)試
- 利用Python的Twisted框架實(shí)現(xiàn)webshell密碼掃描器的教程
- 使用Python的Twisted框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單的服務(wù)器
- 使用Python的Twisted框架編寫(xiě)簡(jiǎn)單的網(wǎng)絡(luò)客戶端
- python開(kāi)發(fā)實(shí)例之Python的Twisted框架中Deferred對(duì)象的詳細(xì)用法與實(shí)例
相關(guān)文章
python之用Numpy和matplotlib畫(huà)一個(gè)魔方
這篇文章主要介紹了如何用Numpy和matplotlib畫(huà)一個(gè)魔方,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08python 實(shí)現(xiàn)批量xls文件轉(zhuǎn)csv文件的方法
今天小編就為大家分享一篇python 實(shí)現(xiàn)批量xls文件轉(zhuǎn)csv文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10Python實(shí)現(xiàn)希爾排序算法的原理與用法實(shí)例分析
這篇文章主要介紹了Python實(shí)現(xiàn)希爾排序算法,簡(jiǎn)單講述了希爾排序的原理并結(jié)合具體實(shí)例形式分析了Python希爾排序的具體實(shí)現(xiàn)方法與使用技巧,需要的朋友可以參考下2017-11-11python實(shí)現(xiàn)由數(shù)組生成對(duì)稱矩陣
本文給大家分享的是由數(shù)組生成對(duì)稱矩陣的思路并附上了使用Python實(shí)現(xiàn)的代碼,希望大家能夠喜歡2021-05-05Pandas數(shù)據(jù)連接pd.concat的實(shí)現(xiàn)
本文主要介紹了Pandas數(shù)據(jù)連接pd.concat的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07關(guān)于PyTorch 自動(dòng)求導(dǎo)機(jī)制詳解
今天小編就為大家分享一篇關(guān)于PyTorch 自動(dòng)求導(dǎo)機(jī)制詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08Python實(shí)現(xiàn)批量獲取當(dāng)前文件夾下的文件名
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)批量獲取當(dāng)前文件夾下的文件名,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02