当前位置: 首页 > 后端技术 > Python

Python的Twisted框架中Deferred对象的详细用法与实例

时间:2023-03-26 13:15:42 Python

Python的Twisted框架中Deferred对象的详细用法和示例对象的用法。Deferred由一系列回调对组成,每对包含一个用于处理成功的回调(callbacks)和一个用于处理错误的回调(errbacks)。最初,deffereds将由两个空的回调链组成。向它们添加回调将始终成对完成。当异步处理的结果返回时,Deferred将启动并按照添加的顺序触发回调链。举个例子可能更容易解释,我们先看addCallback:fromtwisted.internet.deferimportDeferreddefmyCallback(result):printresultd=Deferred()d.addCallback(myCallback)d.callback("触发回调。")运行会得到如下结果:触发回调。在上面的示例中,创建了一个deffered,它的addCallback方法用于注册处理成功的回调。d.callback将延迟启动并调用回调链。传递给回调的参数也由每个回调链中的第一个函数接收。还有addCallback,又是一个错误的分支,我想我可以猜到是addErrorback,我们看一个例子:fromtwisted.internet.deferimportDeferreddefmyErrback(failure):printfailed=Deferred()d.addErrback(myErrback)d。errback(ValueError("Triggeringerrback."))运行它会得到如下结果:[Failureinstance:Traceback(failurewithnoframes)::Triggeringerrback.]可以看出Twisted会将错误封装在Failure中。值得注意的是,如前所述,注册的回调总是成对的。在使用d.addCallback和d.addErrorback方法时,我们似乎只是添加一个回调或一个errback。实际上,为了完成这一层回调链的创建,这些方法还会为另一半注册一个pass-through。请记住,回调链的长度始终相同。如果要分别指定该级别回调的callback和errback。可以使用d.addCallbacks方法:d=Deferred()d.addCallbacks(myCallback,myErrback)d.callback("Triggeringcallback.")接下来要做一些比较实际的事情,就是放到Reactor中。先看一个例子:fromtwisted.internetimportreactor,deferclassHeadlineRetriever(object):defprocessHeadline(self,headline):iflen(headline)>50:self.d.errback(Exception("TheheadlineRetriever(object):defprocessHeadline(self,headline):iflen(headline)>50:self.d.errback(Exception("Theheadline``%s''太长了!"%(headline,)))else:self.d.callback(headline)def_toHTML(self,result):return"

%s

"%(result,)defgetHeadline(self,input):self.d=defer.Deferred()reactor.callLater(1,self.processHeadline,input)self.d.addCallback(self._toHTML)returnself.ddefprintData(result):打印resultreactor.stop()defprintError(failure):printfailurereactor.stop()h=HeadlineRetriever()d=h.getHeadline("BreakingNews:TwistedTakesustotheMoon!")d.addCallbacks(printData,printError)reactor.run()上面的例子接收到一个标题并进行处理。如果标题太长,会返回太长的错误,否则会转成HTML返回。由于给定的标题少于50个字符,执行上面的代码会返回如下:可以作为一个定时事件来模拟异步请求。如果我们把标题做的很长,比如:h=HeadlineRetriever()d=h.getHeadline("1234567890"*6)d.addCallbacks(printData,printError),结果可以满足[Failureinstance:Traceback(failurewith没有框架)::标题“123456789012345678901234567890123456789012345678901234567890”太长了!下面用图来看一下触发过程:Deferreds中的关键点在调用它的callback或errback时会被触发;延迟只能触发一次!如果多次尝试触发,会引发AlreadyCalledError异常;第N级回调或errback中的异常会传递给N+1级errback;如果没有errback,将抛出未处理的错误。如果在N级回调或errback中没有抛出Exception或者返回了Failure对象,则由N+1级回调处理;回调中返回的结果将传递给下一级回调,并作为其第一个参数;如果传递给errback的错误不是Failure对象,它将自动包装一次。