当我通过这个blog中的例子时,我发现当ClientFactory实例(PoetryClientFactory的一个参数)或者是PoetryProtocol的一个参数的Protocol实例时,它没有实现定义的所有函数用于ClientFactory或Protocol接口。 ClientFactory接口实现了startsConnecting,clientConnectionFailed和clientConnectionLost,但是PoetryClientFactory没有实现startedConnecting和clientConnectionLost。怎么了?
# This is the Twisted Get Poetry Now! client, version 2.0.
# NOTE: This should not be used as the basis for production code.
import datetime, optparse
from twisted.internet.protocol import Protocol, ClientFactory
def parse_args():
usage = """usage: %prog [options] [hostname]:port ...
This is the Get Poetry Now! client, Twisted version 2.0.
Run it like this:
python get-poetry.py port1 port2 port3 ...
If you are in the base directory of the twisted-intro package,
you could run it like this:
python twisted-client-2/get-poetry.py 10001 10002 10003
to grab poetry from servers on ports 10001, 10002, and 10003.
Of course, there need to be servers listening on those ports
for that to work.
"""
parser = optparse.OptionParser(usage)
_, addresses = parser.parse_args()
if not addresses:
print parser.format_help()
parser.exit()
def parse_address(addr):
if ':' not in addr:
host = '127.0.0.1'
port = addr
else:
host, port = addr.split(':', 1)
if not port.isdigit():
parser.error('Ports must be integers.')
return host, int(port)
return map(parse_address, addresses)
class PoetryProtocol(Protocol):
poem = ''
task_num = 0
def dataReceived(self, data):
self.poem += data
msg = 'Task %d: got %d bytes of poetry from %s'
print msg % (self.task_num, len(data), self.transport.getPeer())
def connectionLost(self, reason):
self.poemReceived(self.poem)
def poemReceived(self, poem):
self.factory.poem_finished(self.task_num, poem)
class PoetryClientFactory(ClientFactory):
task_num = 1
protocol = PoetryProtocol # tell base class what proto to build
def __init__(self, poetry_count):
self.poetry_count = poetry_count
self.poems = {} # task num -> poem
def buildProtocol(self, address):
proto = ClientFactory.buildProtocol(self, address)
proto.task_num = self.task_num
self.task_num += 1
return proto
def poem_finished(self, task_num=None, poem=None):
if task_num is not None:
self.poems[task_num] = poem
self.poetry_count -= 1
if self.poetry_count == 0:
self.report()
from twisted.internet import reactor
reactor.stop()
def report(self):
for i in self.poems:
print 'Task %d: %d bytes of poetry' % (i, len(self.poems[i]))
def clientConnectionFailed(self, connector, reason):
print 'Failed to connect to:', connector.getDestination()
self.poem_finished()
def poetry_main():
addresses = parse_args()
start = datetime.datetime.now()
factory = PoetryClientFactory(len(addresses))
from twisted.internet import reactor
for address in addresses:
host, port = address
reactor.connectTCP(host, port, factory)
reactor.run()
elapsed = datetime.datetime.now() - start
print 'Got %d poems in %s' % (len(addresses), elapsed)
if __name__ == '__main__':
poetry_main()
答案 0 :(得分:2)
我认为我不确定你在问什么,但基本上如果你不需要对某个事件采取行动(例如当客户开始连接或连接丢失时),你就不要不需要实现这个功能。它主要是一个界面。如果你没有实现这些函数,那么从ClientFactory
或Protocol
或者你继承的任何一个类调用一个不执行任何操作的空函数。
答案 1 :(得分:2)
如果您自己实现界面,它看起来像这样:
from zope.interface import implementer
from twisted.internet.interfaces import IProtocol
@implementer(IProtocol)
class MyProtocol(object):
" ... "
在这种情况下,你做需要实现所有方法,因为这个@implementer
声明只是说你打算提供所有相关的方法。
然而,在Twisted中更常见的事情是子类化,如下所示:
from twisted.internet.protocol import Protocol
class MyProtocol(Protocol, object):
" ... "
在这个的情况下,你不需要实现所有方法,因为Protocol
超类已经提供了{{{{}}上所有方法的实现1}}。通常,Twisted提供了一个超类,它具有Twisted应用程序开发人员必须实现的许多更常用接口的所有方法的默认或空版本。
答案 2 :(得分:0)
我也不太确定你在问什么。
IMO,达到github的source code是最快的学习方式。如您所见, startedConnecting 和 clientConnectionLost (默认为空代码)有默认实现。
因此,您只需要实现所需的回调,而不是该接口中定义的所有方法。