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 相关文章推荐
wxPython事件驱动实例详解
Sep 28 Python
centos 下面安装python2.7 +pip +mysqld
Nov 18 Python
wxPython定时器wx.Timer简单应用实例
Jun 03 Python
python虚拟环境的安装配置图文教程
Oct 20 Python
利用信号如何监控Django模型对象字段值的变化详解
Nov 27 Python
详解python多线程、锁、event事件机制的简单使用
Apr 27 Python
Python闭包执行时值的传递方式实例分析
Jun 04 Python
python中的turtle库函数简单使用教程
Jul 23 Python
python全栈要学什么 python全栈学习路线
Jun 28 Python
python查看文件大小和文件夹内容的方法
Jul 08 Python
Python基于requests库爬取网站信息
Mar 02 Python
使用bandit对目标python代码进行安全函数扫描的案例分析
Jan 27 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
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
php flush类输出缓冲剖析
2008/10/19 PHP
ThinkPHP查询返回简单字段数组的方法
2014/08/25 PHP
ThinkPHP模板中数组循环实例
2014/10/30 PHP
Yii2 rbac权限控制之菜单menu实例教程
2016/04/28 PHP
Yii的Srbac插件用法详解
2016/07/14 PHP
php多进程并发编程防止出现僵尸进程的方法分析
2020/02/28 PHP
js post方式传递提交的实现代码
2010/05/31 Javascript
js arguments对象应用介绍
2012/11/28 Javascript
javascript对象的使用和属性操作示例详解
2014/03/02 Javascript
jQuery实现可用于博客的动态滑动菜单
2015/03/09 Javascript
javascript实现多栏闭合展开式广告位菜单效果实例
2015/08/05 Javascript
老生常谈遮罩层 滚动条的问题
2016/04/29 Javascript
Bootstrap中点击按钮后变灰并显示加载中实例代码
2016/09/23 Javascript
jQuery动态创建元素以及追加节点的实现方法
2016/10/20 Javascript
jQuery简单实现MD5加密的方法
2017/03/03 Javascript
原生JS实现图片网格式渐显、渐隐效果
2017/06/05 Javascript
JS中LocalStorage与SessionStorage五种循序渐进的使用方法
2017/07/12 Javascript
js+css实现打字效果
2020/06/24 Javascript
VeeValidate在vue项目里表单校验应用案例
2018/05/09 Javascript
微信小程序实现tab左右切换效果
2020/11/15 Javascript
微信小程序服务器日期格式化问题
2020/01/07 Javascript
uni-app使用countdown插件实现倒计时
2020/11/01 Javascript
[03:30]完美盛典趣味短片 CSGO2019年度名场面
2019/12/07 DOTA
Python下载懒人图库JavaScript特效
2015/05/28 Python
Python基础篇之初识Python必看攻略
2016/06/23 Python
利用Tkinter(python3.6)实现一个简单计算器
2017/12/21 Python
python中正则表达式的使用方法
2018/02/25 Python
深入浅析Python中的迭代器
2019/06/04 Python
解决Django layui {{}}冲突的问题
2019/08/29 Python
python 爬取马蜂窝景点翻页文字评论的实现
2020/01/20 Python
如何使用Cython对python代码进行加密
2020/07/08 Python
会计岗位职责
2013/11/08 职场文书
宪法宣传标语100条
2019/10/15 职场文书
SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串
2022/05/25 SQL Server
HTML实现仿Windows桌面主题特效的实现
2022/06/28 HTML / CSS