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