一、开篇

  为什么是twisted,twisted作为一个python网络编程框架,出道早,但一直不温不火,这几年和tornado比起来,更是近乎销声匿迹;但作为初学者,觉得twisted还是有很多优点值得去学习的,其优秀的性能(对python框架)其实更适合做底层的tcp server,而且个人觉得twisted deferred的设计思路非常简单清晰,相较于tornado future异步更好理解,缺点可能就是源码不好读,然后如果拿来直接开发web不是很方便。但还是那句话,twisted flask tornado gevent都有自己比较鲜明的特征,值得去学习下。

  博主也是初学,写这个博客也是想作为一个学习记录,如果有问题大家可以一起探讨,有出错的地方还请指出,谢谢。

二、认识Deferred

  Deferred是一个延迟加载对象,这个概念类似于tornado future,是调用异步操作返回的一个对象,其中包括了操作成功后的回调处理,错误后的回调处理。

  简单讲,当我们需要执行一个耗时操作,比如下载某个大图片,此时用twisted的异步http请求,会给我们返回一个Deferred对象,让我们可以不用在这等图片下载完成,当前线程不会阻塞,而是可以去处理别的逻辑。twisted有一个底层event loop(类似tornado ioloop)处理线程),等图片下载完成后,会去自动触发Deferred的回调操作,这个细节我们不需要操作,我们要做的,就是添加这个回调逻辑,也就是常说的注册回调。

  下面有个简单例子

  1. # coding:utf-8
  2.  
  3. import time
  4.  
  5. from twisted.internet import defer, reactor
  6.  
  7. class deferTester():
  8.  
  9. def __init__(self):
  10. self.d = defer.Deferred()
  11.  
  12. def getDefer(self):
  13. return self.d
  14.  
  15. #模拟耗时操作
  16. def work(self):
  17. print "[%s] 模拟耗时网络IO, 等待3秒" % nowtime()
  18. time.sleep(3)
  19. self.d.callback('over') # 因为是模拟的IO,任务完成后手动触发回调
  20.  
  21. #处理成功回调
  22. def handle_success(self,d):
  23. print "[%s] 成功, 接收参数 = " % nowtime(), d
  24. a = [1, 2, 3][4] # 这里会抛异常,添加到defered的errback链,然后由handle_error处理
  25. #处理异常回调
  26. def handle_error(self,d):
  27. print "[%s] 出错了" % nowtime(), repr(d)
  28.  
  29. def stop():
  30. reactor.stop()
  31. print "[%s] 停止reactor"%nowtime()
  32.  
  33. def nowtime():
  34. return time.strftime('%Y-%m-%d,%X', time.localtime())
  35.  
  36. if __name__ == '__main__':
  37. print "[%s] 开始测试 "%nowtime()
  38. tester = deferTester()
  39. d = tester.getDefer() #拿到defered对象
  40. reactor.callWhenRunning(tester.work)#reactor调用耗时任务
  41. d.addCallback(tester.handle_success)
  42. d.addErrback(tester.handle_error)#defered对象添加处理的回调
  43. print "[%s] 启动reactor "%nowtime()
  44. reactor.callLater(5, stop) #5秒后停止reactor线程
  45. reactor.run()

例子很简单,看下注释就清楚了,运行结果为

  1. [2018-10-25,16:10:38] 开始测试
  2. [2018-10-25,16:10:38] 启动reactor
  3. [2018-10-25,16:10:38] 模拟耗时网络IO, 等待3
  4. [2018-10-25,16:10:41] 成功, 接收参数 = over
  5. [2018-10-25,16:10:41] 出错了 <twisted.python.failure.Failure exceptions.IndexError: list index out of range>
  6. [2018-10-25,16:10:43] 停止reactor

  有几点要注意下:

  1. 正常情况下,我们调用twisted的异步http client,会返回一个deferred对象,然后IO完成后,会自动触发deferred对象的事件,但我们这个例子只是简单的用time.sleep()模拟了下耗时操作,所以操作完成后,需要手动callback()去触发成功回调,实际编程中一般是不需要我们自己去触发的。

  2. deferred有两条回调链,分别是callback和errback,其中errback也非常重要,因为我们业务不可能次次都调用成功,添加异常处理是必需的!我们不需要再异步中去try except捕捉异常,只需要在上层调用中添加一个回调就可以,因为比如在N层回调中出现了异常,错误信息会记录在errback链中,在N-1层逻辑添加回调就可以了。

    如上面的例子,work操作完成后 ---> 触发handle_success回调,但是在handle_success里出现了错误,这个错误会自动以Failure对象记录到errback链中,我们只需要注册一个errback的处理逻辑就可以了,如handle_error,它接受的参数就是Failure对象。

  

(一)使用twisted Deferred的更多相关文章

  1. [Twisted] deferred

    Twisted提供一个优雅的实现(Deferred)来管理回调函数. Deferred Object 的结构 Deferred Object包含两个回调函数列表.一个用来保存成功的回调函数,另一个用来 ...

  2. 爬虫基础(五)-----scrapy框架简介

    ---------------------------------------------------摆脱穷人思维 <五> :拓展自己的视野,适当做一些眼前''无用''的事情,防止进入只关 ...

  3. 5、爬虫系列之scrapy框架

    一 scrapy框架简介 1 介绍 (1) 什么是Scrapy? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架就是一个已经被集成了各种功能(高性能 ...

  4. python 全栈开发,Day137(爬虫系列之第4章-scrapy框架)

    一.scrapy框架简介 1. 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前S ...

  5. 四: scrapy爬虫框架

    5.爬虫系列之scrapy框架   一 scrapy框架简介 1 介绍 (1) 什么是Scrapy? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架 ...

  6. 笔记-scrapy-pipeline

    笔记-scrapy-pipeline 1.简介 scrapy抓取数据后,使用yield发送item对象至pipeline,pipeline顺序对item进行处理. 一般用于: 清洗,验证,检查数据: ...

  7. scrapy框架之Pipeline管道类

    Item Pipeline简介 Item管道的主要责任是负责处理有蜘蛛从网页中抽取的Item,他的主要任务是清洗.验证和存储数据.当页面被蜘蛛解析后,将被发送到Item管道,并经过几个特定的次序处理数 ...

  8. 如何用item pipeline(管道)清洗数据

    版权声明:本文为博主原创文章,转载请注明出处:如果博客中有错误之处抑或有可以改进的地方,欢迎在评论区留言. https://blog.csdn.net/f156207495/article/detai ...

  9. 小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

随机推荐

  1. luogu 3441 [POI2006]MET-Subway 拓扑排序+思维

    Description 给出一棵N个结点的树,选择L条路径,覆盖这些路径上的结点,使得被覆盖到的结点数最多. Input 第一行两个正整数N.L(2 <= N <= 1,000,000, ...

  2. Sogou for Linux

    造冰箱的大熊猫,本文适用于Ubuntu 18.04@cnblogs 2019/5/8 在Ubuntu(安装时选择英文语言环境)下安装搜狗输入法 1)从搜狗官网下载sogou拼音输入法的deb安装包. ...

  3. Codevs 4829 [DP]数字三角形升级版

    4829 [DP]数字三角形升级版 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description 从数字三角形的顶部(如图,第一行的5表示行数)到底 ...

  4. zabbix企业微信告警配置教程

    前言: zabbix企业微信告警只需要配置一次就可以使用很久了,但是发现再次配置时,总会有遗忘,很麻烦又要去重新熟悉,所以,现在记录一份详细的配置过程,方便日后再次配置. 1.zabbix_serve ...

  5. zookeeper系列(五)zookeeper在大型分布式系统中的应用

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败. 出处:http://www.cnblogs.com/leesf456/p/6063694.html 尊重原创感谢博主公开这么好的博文, ...

  6. flask登录功能实现的思路

    flask登录实现过程思路:前端创建表单,post方法,userno,pwd参数 后端首先创建登录验证函数check(验证函数是指通过request.get来获取前端的userno,pwd.然后将两个 ...

  7. WebSocket-java实现

    一.所需jar 二.创建websocket.jsp(注意此页面链接,需要链接到自己的服务) <%@ page language="java" import="jav ...

  8. STL -- heap结构及算法

    STL -- heap结构及算法 heap(隐式表述,implicit representation) 1. heap概述 : vector + heap算法 heap并不归属于STL容器组件,它是个 ...

  9. Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name) 中文显示乱码

    如果file.Name为中文则乱码.解决办法是方法1:response.setHeader("Content-Disposition", "attachment; fil ...

  10. Class 源码解读

    Class 获取包信息 /** * 获取此对象所在的包 * @revised 9 * @spec JPMS */ public Package getPackage() { // 原始类型和数组无 P ...