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


Posted in Python onMarch 19, 2020

Deferred对象在Twsited框架中用于处理回调,这对于依靠异步的Twisted来说十分重要,接下来我们就以实例解析Python的Twisted框架中Deferred对象的用法

Deferred对象结构

Deferred由一系列成对的回调链组成,每一对都包含一个用于处理成功的回调(callbacks)和一个用于处理错误的回调(errbacks)。初始状态下,deffereds将由两个空回调链组成。在向其中添加回调时将总是成对添加。当异步处理中的结果返回时,Deferred将会启动并以添加时的顺序触发回调链。

用实例也许更容易说明,首先来看看addCallback:

from twisted.internet.defer import Deferred
 
def myCallback(result):
 print result
 
d = Deferred()
d.addCallback(myCallback)
d.callback("Triggering callback.")

运行它将会得到如下结果:

Triggering callback.

上例中创建了一个deffered并利用其addCallback方法注册一个用于处理成功的回调。d.callback会启动deffered并调用callback链。传入callback的参数也会被各callback链中的第一个函数接收到。

有addCallback,那另一个错误的分支,我想也能猜测到了那就是addErrorback,同样来看个例子:

from twisted.internet.defer import Deferred
 
def myErrback(failure):
 print failure
 
d = Deferred()
d.addErrback(myErrback)
d.errback(ValueError("Triggering errback."))

运行它将会得到如下结果:

[Failure instance: Traceback (failure with no frames): <type 'exceptions.ValueError'>: Triggering errback.]

可以看出Twisted会把错误封装在Failure里。

值得注意的是,在之前提到过注册回调总是成对的。在使用d.addCallback和d.addErrorback方法时,我们看似只是添加了一个callback或一个errback。而实际上,为了完成这一级回调链的创建,这些方法还会为另一半注册一个pass-through。要记住,回调链总是具有相同的长度。如果要分别指定这一级回调的callback和errback。可以使用d.addCallbacks方法:

d = Deferred()
d.addCallbacks(myCallback, myErrback)
d.callback("Triggering callback.")

进阶示例

接下来就应该来点更为实际的,那就是放进Reactor。先来看一个例子:

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()

上例接收一个标题并对其进行处理,如果标题超长会返回超长的错误,否则将其转为HTML并返回。

因所给的标题少于50个字符,故执行以上代码会得到如下返回:

<h1>Breaking News: Twisted Takes us to the Moon!</h1>

有一点值得注意的,上面用到了reactor的callLater方法,它可以用来做定时事件从而模拟一个异步的请求。

如果我们将标题变得很长,比如说:

h = HeadlineRetriever()
d = h.getHeadline("1234567890"*6)
d.addCallbacks(printData, printError)

那结果是可以遇见的

[Failure instance: Traceback (failure with no frames): : The headline ``123456789012345678901234567890123456789012345678901234567890'' is too long!]

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

我们用图看一下触发流程:

  • Deferreds中的关键之处
  • Deferreds将会在调用其callback或errback时被触发;
  • Deferreds仅能被触发一次!如果尝试多次触发将会导致AlreadyCalledError异常;
  • 第N级callback或errback中的Exceptions将会传入第N+1级的errback中;如果没有errback,则会抛出Unhandled Error。如果第N级callback或errback中没有抛出Exception或返回Failure对象,那接下来将会由第N+1级中的callback进行处理;
  • callback中返回的结果将会传入下一级callback,并作为其第一个参数;
  • 如果传入errback的错误不是一个Failure对象,那将会被自动包装一次。

本文主要用实例讲解了Python的Twisted框架中Deferred对象的详细用法,更多关于Python的Twisted框架知识技巧请查看下面的相关链接

Python 相关文章推荐
Python素数检测实例分析
Jun 15 Python
Python中list初始化方法示例
Sep 18 Python
TF-IDF算法解析与Python实现方法详解
Nov 16 Python
python-opencv颜色提取分割方法
Dec 08 Python
自学python的建议和周期预算
Jan 30 Python
Python实现的IP端口扫描工具类示例
Feb 15 Python
python快排算法详解
Mar 04 Python
wxPython窗体拆分布局基础组件
Nov 19 Python
利用pytorch实现对CIFAR-10数据集的分类
Jan 14 Python
基于Python计算圆周率pi代码实例
Mar 25 Python
Python实现自动签到脚本的示例代码
Aug 19 Python
基于Python实现体育彩票选号器功能代码实例
Sep 16 Python
mac 上配置Pycharm连接远程服务器并实现使用远程服务器Python解释器的方法
Mar 19 #Python
python数据库开发之MongoDB安装及Python3操作MongoDB数据库详细方法与实例
Mar 18 #Python
Python3开发实例之非关系型图数据库Neo4j安装方法及Python3连接操作Neo4j方法实例
Mar 18 #Python
selenium+python配置chrome浏览器的选项的实现
Mar 18 #Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
Mar 18 #Python
python selenium操作cookie的实现
Mar 18 #Python
Selenium 滚动页面至元素可见的方法
Mar 18 #Python
You might like
德生S2000电路分析
2021/03/02 无线电
关于UEditor编辑器远程图片上传失败的解决办法
2012/08/31 PHP
利用PHP生成静态HTML文档的原理
2012/10/29 PHP
php实现图片添加水印功能
2014/02/13 PHP
php获取开始与结束日期之间所有日期的方法
2016/11/29 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
2017/06/21 PHP
php生成word并下载代码实例
2019/03/15 PHP
php实现推荐功能的简单实例
2019/09/29 PHP
JavaScript 克隆数组最简单的方法
2009/02/12 Javascript
js实现两点之间画线的方法
2015/05/12 Javascript
jQuery实现的多级下拉菜单效果代码
2015/08/24 Javascript
js图片跟随鼠标移动代码
2015/11/26 Javascript
详解js跨域原理以及2种解决方案
2015/12/09 Javascript
jquery实现鼠标悬浮停止轮播特效
2020/08/20 Javascript
js剪切板应用clipboardData实例解析
2016/05/29 Javascript
jquery+ajax实现省市区三级联动效果简单示例
2017/01/04 Javascript
AngularJS实用基础知识_入门必备篇(推荐)
2017/07/10 Javascript
Vue.js进行查询操作的实例详解
2017/08/25 Javascript
VUE组件中的 Drawer 抽屉实现代码
2019/08/06 Javascript
Element el-button 按钮组件的使用详解
2021/02/01 Javascript
[37:35]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第二局
2016/02/25 DOTA
利用Anaconda完美解决Python 2与python 3的共存问题
2017/05/25 Python
人工智能最火编程语言 Python大战Java!
2017/11/13 Python
Python脚本修改阿里云的访问控制列表的方法
2019/03/08 Python
超简单使用Python换脸实例
2019/03/27 Python
解决python执行不输出系统命令弹框的问题
2019/06/24 Python
python3 字符串知识点学习笔记
2020/02/08 Python
寻找迷宫的一条出路,o通路;X:障碍
2016/07/10 面试题
车间机修工岗位职责
2014/02/28 职场文书
化学专业毕业生求职信
2014/07/28 职场文书
月度优秀员工获奖感言
2014/08/16 职场文书
学术研讨会欢迎词
2015/01/26 职场文书
2015年医院工作总结范文
2015/04/09 职场文书
Html5生成验证码的示例代码
2021/05/10 Javascript
Python人工智能之混合高斯模型运动目标检测详解分析
2021/11/07 Python
css中:last-child不生效的解决方法
2022/08/05 HTML / CSS