9.defer專題

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對象包裝的異常。react

defer中比較經常使用的:web

from twisted.internet import threads編程

threads.deferToThread()     把一個堵塞的函數放到線程中去執行, 返回一個defer對象。app

相關文章
相關標籤/搜索