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通过定义一个类实例作为ftp回调方法
May 04 Python
Python统计文件中去重后uuid个数的方法
Jul 30 Python
python函数的5种参数详解
Feb 24 Python
python3使用pyqt5制作一个超简单浏览器的实例
Oct 19 Python
Python内置函数—vars的具体使用方法
Dec 04 Python
unittest+coverage单元测试代码覆盖操作实例详解
Apr 04 Python
在Django的View中使用asyncio的方法
Jul 12 Python
python基于TCP实现的文件下载器功能案例
Dec 10 Python
解决pyPdf和pyPdf2在合并pdf时出现异常的问题
Apr 03 Python
使用Keras预训练模型ResNet50进行图像分类方式
May 23 Python
selenium判断元素是否存在的两种方法小结
Dec 07 Python
Python使用tkinter实现小时钟效果
Feb 22 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
一个php作的文本留言本的例子(六)
2006/10/09 PHP
php中取得URL的根域名的代码
2011/03/23 PHP
采集邮箱的php代码(抓取网页中的邮箱地址)
2012/07/17 PHP
8个必备的PHP功能实例代码
2013/10/27 PHP
分享下页面关键字抓取www.icbase.com站点代码(带asp.net参数的)
2014/01/30 PHP
PHP中addslashes与mysql_escape_string的区别分析
2016/04/25 PHP
PHP数据库表操作的封装类及用法实例详解
2016/07/12 PHP
javascript基于DOM实现权限选择实例分析
2015/05/14 Javascript
HTML5之WebSocket入门3 -通信模型socket.io
2015/08/21 Javascript
如何实现移动端浏览器不显示 pc 端的广告
2015/10/15 Javascript
C#微信小程序服务端获取用户解密信息实例代码
2017/03/10 Javascript
解决Vue页面固定滚动位置的处理办法
2017/07/13 Javascript
Vue 中批量下载文件并打包的示例代码
2017/11/20 Javascript
AngularJS实现的2048小游戏功能【附源码下载】
2018/01/03 Javascript
Vue.js 动态为img的src赋值方法
2018/03/14 Javascript
详解Nodejs mongoose
2018/06/10 NodeJs
JavaScript创建对象的常用方式总结
2018/08/10 Javascript
Vue2.x通用条件搜索组件的封装及应用详解
2019/05/28 Javascript
实现一个 Vue 吸顶锚点组件方法
2019/07/10 Javascript
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
放弃 Python 转向 Go语言有人给出了 9 大理由
2017/10/20 Python
transform python环境快速配置方法
2018/09/27 Python
python中logging模块的一些简单用法的使用
2019/02/22 Python
完美解决python3.7 pip升级 拒绝访问问题
2019/07/12 Python
Pytorch训练过程出现nan的解决方式
2020/01/02 Python
Pycharm中import torch报错的快速解决方法
2020/03/05 Python
中国网上药店领导者:1药网
2017/02/16 全球购物
美国嘻哈文化生活方式品牌:GLD
2018/04/15 全球购物
Belstaff英国官方在线商店:Belstaff.co.uk
2021/02/09 全球购物
给排水专业应届生求职信
2013/10/12 职场文书
《将心比心》教学反思
2014/04/08 职场文书
安全横幅标语
2014/06/09 职场文书
学校消防安全责任书
2014/07/23 职场文书
自主招生自荐信怎么写
2015/03/24 职场文书
2016年校园植树节广播稿
2015/12/17 职场文书
比较几种Redis集群方案
2021/06/21 Redis