什么是defer?

Twisted是一个使用协程实现多并发、异步编程的python框架。类似的框架还有gevent。

defer是Twisted框架的一个组件(一个py文件,链接点我),Deferred是里面的一个类。
defer本身是类似于一个承诺(promise)、一个占位符(placeholder)这样的东西。
它表示的是一个方法现在不一定马上返回但将来可能会返回一个值。它的目的是为了可以不按照流式的方式执行代码(不会阻塞在某块,也就是异步编程),而是可以把自己想要的流程、计划,通过程序语言表述出来。

比如下面这样的代码:

x = func_a()
func_b(x)
func_c()

正常情况下程序语句总是执行完了一句再执行下一句,所以如果func_a一直没返回并赋值给x,那func_b就没法执行,程序就会阻塞在那里,一直到func_a执行结束。更后续的func_c()也不会执行,即使func_c跟func_a的返回值没关。

如果使用Deferred的话,我们就可以这样写:

d = defer.Deferred()
d = func_a()
d.addCallback(func_b)
func_c()

有了这样一种机制,就可以实现异步编程,在诸如有很多网络IO的任务中(网络、IO的速度都比CPU速度要慢很多很多,没必要发了一个请求还得在那等着响应返回,完全可以先去做别的事,或者继续发更多的请求 ),使用defer就可以实现多并发。

另一种常用的实现并发的方式是多线程,而defer用到的其实是协程的概念。

所谓协程,可以理解为微线程,轻量级的线程。像上面的代码,如果让func_c和func_a实现并发的话,就得至少开两个线程。defer就根本不用写多线程相关的代码,它内部其实都是在一个线程里的。实际有人测试过一万个网络请求并发,用tornado的gen(也是个协程框架)和使用多线程的方式(开一万个线程),后者几乎崩溃,前者速度还是很可观。

不过,defer虽然可以让程序流往下执行下去,但需要耗时间的任务还是得耗。

Twisted官网关于defer的介绍原文链接如下:
http://twistedmatrix.com/documents/current/core/howto/defer-intro.html
使用异步的原因,好处等等。
http://twistedmatrix.com/documents/current/core/howto/defer.html
defer核心概念
http://twistedmatrix.com/documents/current/core/howto/gendefer.html
更多关于defer的内容