接上篇,我们来看看怎么分别用defer和reactor来实现同样的http客户端。
这个是官方文档给的例子,使用了defer: <pre class=python name=code> from pprint import pformat
from twisted.internet import reactor from twisted.internet.defer import Deferred from twisted.internet.protocol import Protocol from twisted.web.client import Agent from twisted.web.http_headers import Headers
class BeginningPrinter(Protocol): def init(self, finished): self.finished = finished self.remaining = 1024 * 10
def dataReceived(self, bytes):
if self.remaining:
display = bytes[:self.remaining]
print 'Some data received:'
print display
self.remaining -= len(display)
def connectionLost(self, reason):
print 'Finished receiving body:', reason.getErrorMessage()
self.finished.callback(None)
agent = Agent(reactor) d = agent.request( ‘GET’, ‘http://example.com/’, Headers({‘User-Agent’: [‘Twisted Web Client Example’]}), None)
def cbRequest(response): print ‘Response version:’, response.version print ‘Response code:’, response.code print ‘Response phrase:’, response.phrase print ‘Response headers:’ print pformat(list(response.headers.getAllRawHeaders())) finished = Deferred() response.deliverBody(BeginningPrinter(finished)) return finished d.addCallback(cbRequest)
def cbShutdown(ignored): reactor.stop() d.addBoth(cbShutdown)
reactor.run() </pre>
下面是只用reactor实现的例子: <pre class=python name=code> from twisted.internet import protocol, reactor, defer, utils, interfaces from twisted.web import http, client
class HTTPClient(http.HTTPClient): def init(self, fatcory): self._factory = fatcory
def connectionMade(self):
print 'connected'
self.sendCommand('GET', self._factory.url)
self.sendHeader('User-Agent', 'Twisted Web Client Example')
self.endHeaders()
def handleStatus(self, version, status, message):
print("%s %s %s\r\n" %(version, status, message))
def handleHeader(self, key, val):
print("%s: %s\r\n" %(key, val))
def handleEndHeaders(self):
print("\r\n")
def rawDataReceived(self, data):
print(data)
def handleResponseEnd(self):
reactor.stop()
class HTTPClientFactory(client.HTTPClientFactory): def init(self, url): client.HTTPClientFactory.init(self, url) self.url = url
def buildProtocol(self, addr):
return HTTPClient(self)
reactor.connectTCP(‘google.com’, 80, HTTPClientFactory(‘/’))
reactor.run()
</pre>
是不是比defer要清晰一点,可能也有其他场景下使用defer要更好点,但是初学可以选择从reactor入手,能更快的熟悉这个框架。