deferred为twisted中异步调用功能的核心体现。
deferred作用可以理解为:类似一个寻呼机,它提供了让程序查找非同步任务完成的一种方式,而在这时还可以做其他事情。当函数返回一个Deferred对象时,说明获得结果之前还需要一段时间。为了在任务完成时获取结果,可以Deferred指定一个事件处理器。
clllback方法可以用来获取返回值。   
errback方法来获取异常
__author__ = 'zhoukunpeng'
from twisted.internet import  reactor,defer,protocol
class defferCallBackProtocol(protocol.Protocol):
    def connectionMade(self):
        self.factory.deferred.callback("Connection success")
        self.transport.loseConnection()
class defferCallBackFactory(protocol.ClientFactory):
    protocol=defferCallBackProtocol
    def __init__(self):
        self.deferred=defer.Deferred()
    def clientConnectionFailed(self, connector, reason):
        self.deferred.errback(reason)
def success(result,port):       #result由deferred.callback("Connection success")调用时传入
    print result,"to ",port
    #reactor.stop()
def error(reason,port):         #同上
    print "failed to ",port,":",reason.getErrorMessage()
    #reactor.stop()
testFactory=defferCallBackFactory()
port=80
reactor.connectTCP("10.0.20.150",port,testFactory)
testFactory.deferred.addCallback(success,port)
testFactory.deferred.addErrback(error,port)
reactor.run()
一般一个twisted中仅仅具有一个Deferred, 如果想要保持一串的Deffered呢? 有时确实需要同时保持多个非同步任务,且并非同时完成。此时就必须使用DeferredList对象,通过此对象挂载多个Deferred对象。
defered 和yield过程化编程:
#coding:utf8
from twisted.internet import  reactor,protocol
from twisted.web import client
from twisted.internet import  defer
import  re
from twisted.application.service import Application,Service
from twisted.internet.task import deferLater,LoopingCall,Clock
IP=""
import base64
def sleep(seconds):
    a=defer.Deferred()
    a.addCallback(lambda x:True)
    reactor.callLater(5,a.callback,True)
    return a
base64str=base64.b64encode("zhoukunpeng504:13523136191")
@defer.inlineCallbacks
def callBack(result):
    global IP
    ip=re.search("\d+\.\d+\.\d+\.\d+",result)
    host_ip=ip.group(0)
    print host_ip
    if IP!=host_ip:
        IP=host_ip
        page= yield client.getPage("http://zhoukunpeng.sinaapp.com/host?host=%s"%IP)
        client.getPage("http://ddns.oray.com/ph/update?hostname=wolover.oicp.net&myip=%s"%IP,method="GET",headers={'host':'ddns.oray.com',"Authorization":'Basic %s'%base64str,"Use\
r-Agent":'Oray'}).addCallback(callBack_1)
@defer.inlineCallbacks
def callBack_1(result):
    print result
    yield sleep(10)
    result= yield client.getPage("http://ddns.oray.com/ph/update?hostname=wolover.oicp.net&myip=%s"%IP,method="GET",headers={'host':'ddns.oray.com',"Authorization":'Basic %s'%base64str,"Use\
r-Agent":'Oray'})
    yield  sleep(10)
    result= yield client.getPage("http://ddns.oray.com/ph/update?hostname=wolover.oicp.net&myip=%s"%IP,method="GET",headers={'host':'ddns.oray.com',"Authorization":'Basic %s'%base64str,"Use\
r-Agent":'Oray'})
    print "success!"
def run():
    defer=client.getPage("http://www.ip138.com/ip2city.asp")
    defer.addCallback(callBack)
    reactor.callLater(10,run)
reactor.callWhenRunning(run)
reactor.run()
application=Application("IpMonitor")
五。DeferredList  应用
__author__ = 'zhoukunpeng'
from twisted.internet import  reactor,defer,protocol
class defferCallBackProtocol(protocol.Protocol):
    def connectionMade(self):
        self.factory.deferred.callback("Connection success")
        self.transport.loseConnection()
class defferCallBackFactory(protocol.ClientFactory):
    protocol=defferCallBackProtocol
    def __init__(self):
        self.deferred=defer.Deferred()
    def clientConnectionFailed(self, connector, reason):
        self.deferred.errback(reason)
def success(result,port):
    print result,"to ",port
    #reactor.stop()
def error(reason,port):
    print "failed to ",port,":",reason.getErrorMessage()
    #reactor.stop()
def ListSuccess(results,ports):         #results由deferred.callback("Connection success")中(True,“Connection                                                  #success)   (False,Failure异常对象)组成的一个列表”
    for port,resultInfo in zip(ports,results):
        success,result=resultInfo
        if success:
            print "success to port:",port
    reactor.stop()
def connect(port):
    testFactory=defferCallBackFactory()
    reactor.connectTCP("10.0.0.9",port,testFactory)
    return  testFactory.deferred
_list=[connect(port) for port in range(1,200)]
defer.DeferredList(_list,consumeErrors=True).addCallback(ListSuccess,range(1,200))
reactor.run()
DeferredList包装Deferred,    DeferredList将会跟踪所有的Deferred对象的结果并传递为首参数,当他们都完成了得时候,将会回调按照(success,result)的格式,在Deferred完成时,第一个回传值是True,第二个参数为Deferred传回结果。如果执行失败,则第一个参数是False且第二个参数是Failure对象包装的异常。

defer中比较常用的:

from twisted.internet import threads

threads.deferToThread()     把一个堵塞的函数放到线程中去执行, 返回一个defer对象。

posted on 2016-08-08 15:49  wolover  阅读(269)  评论(0编辑  收藏  举报