Twisted Python接口实例不能实现该接口的所有功能吗?

2024-04-25 14:48:47 发布

您现在位置:Python中文网/ 问答频道 /正文

当我浏览这个blog中的示例时,我发现当ClientFactory实例(PoetryClientFactory的参数)或Protocol实例(PoetryProtocol的参数)没有实现为ClientFactory或Protocol接口定义的所有函数时。ClientFactory接口实现StartedConnection、clientConnectionFailed和clientConnectionLost,但PoetryClientFactory不实现StartedConnection和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()

Tags: thetoselftaskdatetimepoetryifport
3条回答

我也不太清楚你在问什么。你知道吗

在我看来,到达github获取他们的source code是最快的学习方式。如您所见,startedConnectingclientConnectionLost都有默认的实现(不过代码是空的)。你知道吗

因此,您只需要实现所需的回调,而不是该接口中定义的所有方法。你知道吗

如果您自己实现一个接口,它看起来是这样的:

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超类已经提供了IProtocol上所有方法的实现。一般来说,Twisted提供了一个超类,其中包含Twisted应用程序开发人员必须实现的许多更常用接口的所有方法的默认或空版本。你知道吗

我不太清楚你在问什么,但基本上如果你不需要对某个事件采取行动(比如当客户端开始连接或连接丢失时),你就不需要实现这个功能。它主要只是一个接口。如果不实现这些函数,则会从ClientFactoryProtocol或从中继承的任何类调用不执行任何操作的空函数。。你知道吗

相关问题 更多 >