twisted Defer

延迟(Defer)机制时Twisted框架中实现异步编程的体系,使得程序设计可以采用事件驱动的机制

Defer

可以将Twisted中的Defer看作一个管理回调函数的对象,开发者可以向该函数添加需要回调的函数,同时可以指定该组函数何时被调用

  • addCallback(self,callback,*args,**kw):添加正常处理回调函数,其中callback是回调函数名,args和kw是传递给回调函数的参数。其中回调函数至少应该具有一个输入参数
  • addErrback(self,callback,*args,**kw):添加错误处理回调函数
  • addBoth(self,callback,*args,**kw):一个回调函数同时作为正常、异常处理的回调函数
  • chainDeferred(self,d):将另外一个Defer对象(参数d)的正确、错误处理函数添加到当前Defer对象中。本函数具有单向性。(当前Defer调用回调函数不会导致另外一个Defer对象(参数d)的回调函数被调用)
  • callback(self,result):调用正常处理函数链,其中result是传递给第一个正常回调函数的参数。
  • errback(self,fail=None):调用异常处理函数链,其中fail是传递给第一个异常回调函数的参数。
  • pause(self)/unpause(self):暂停、继续对象调用链

Defer对象的回调函数只能由callback()、errback()进行一次调用。如果试图二次调用,框架会抛出异常。

reactor

callLater是Twisted中关键的异步调用函数

  • callLater(delay,callable,*args,**kw):参数delay定义延时调用的秒数,callable参数是回调函数,args、kw是参数
  • stop():终止reactor.run()的挂起
  • run():挂起运行
# coding:utf8
from twisted.internet import reactor,defer

d =defer.Deferred()

def print_square(d):
    print('square of %d is %d'%(d,d*d))
    return d

def print_twice(d):
    print('twice of %d is %d'%(d,2*d))
    return d

def process_error(f):
    print('error when process')

def make_defer():
    d.addCallback(print_square)
    d.addCallback(print_twice)
    d.addErrback(process_error)
    reactor.callLater(2,d.callback,5)

make_defer()
reactor.run()

# 输出:(注册的两个回调函数都被调用)
# square of 5 is 25
# twice of 5 is 10
# coding:utf8
from twisted.internet import reactor

# 定义4秒钟后调用reactor.stop()
reactor.callLater(4,reactor.stop)
reactor.run()
print('Program finished!')

deferToThread

threads.deferToThread 创建Defer,在指定函数执行结束后自动调用callback函数,实现异步编程模式

可以调用Defer的addTimeout添加超时处理函数

  • addTimeout(timeout, clock, onTimeoutCancel=None)

    timeout :超时时间

    clock:twisted.internet.interfaces.IReactorTime,可以使用reactor

    onTimeoutCancel:超时回调函数

from twisted.internet import reactor, threads
import time

def doLongCalculation(x):
    # .... do long calculation here ...
    time.sleep(5)
    return 3*9

def printResult(x):
    print(x)

def logTimeout(result, timeout):
    '''
    defer 超时处理
    :param result: 执行超时的函数句柄
    :param timeout: 超时时间(秒)
    :return:
    '''
    print("Got {0!r} but actually timed out after {1} seconds".format(
        result, timeout))
    return result + " (timed out)"

d = threads.deferToThread(doLongCalculation,9)
d.addTimeout(2,reactor,logTimeout) # 添加超时处理函数,必须在addCallback函数前调用!!!
d.addCallback(printResult)

reactor.run()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值