简体   繁体   English

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

[英]Can Twisted Python interface instance not implementing all functions of that interface?

As I am going through the example in this blog , I found that when ClientFactory instance, which is an argument to PoetryClientFactory, or Protocol instance, which is an argument to PoetryProtocol, is not implementing all the functions defined for ClientFactory or Protocol interface. 在浏览本博客中的示例时,我发现当ClientFactory实例(它是PoetryClientFactory的一个参数)或Protocol实例(它是PoetryProtocol的一个参数)没有实现为ClientFactory或Protocol接口定义的所有功能时。 ClientFactory interface implements startedConnecting, clientConnectionFailed, and clientConnectionLost, but PoetryClientFactory does not implement startedConnecting and clientConnectionLost. ClientFactory接口实现startedConnecting,clientConnectionFailed和clientConnectionLost,但PoetryClientFactory不实现startedConnecting和clientConnectionLost。 What is happening? 怎么了?

# 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()

I don't think I'm quite sure what you're asking, but essentially if you don't need to act on a certain event (such as when a client starts connecting or a connection is lost), you don't need to implement that function. 我不确定我要问的是什么,但是从本质上讲,如果您不需要对某个事件采取行动(例如,当客户端开始连接或连接断开时),则不需要实现该功能。 It's just an interface mostly. 它主要只是一个界面。 If you don't implement those functions, an empty function that does nothing is called, from ClientFactory or Protocol , or whichever class you inherit from.. 如果您不实现这些功能,则会从ClientFactoryProtocol或您继承的任何类中调用一个不执行任何操作的空函数。

If you are implementing an interface yourself, it looks like this: 如果您自己实现接口,则它看起来像这样:

from zope.interface import implementer
from twisted.internet.interfaces import IProtocol
@implementer(IProtocol)
class MyProtocol(object):
    " ... "

In this case, you do need to implement all methods, because this @implementer declaration is just saying that you intend to provide all the relevant methods. 在这种情况下,您确实需要实现所有方法,因为此@implementer声明仅表示您打算提供所有相关方法。

However, the more common thing to do in Twisted is to subclass, like this: 但是,在Twisted中更常见的做法是子类化,如下所示:

from twisted.internet.protocol import Protocol
class MyProtocol(Protocol, object):
    " ... "

In this case, you do not need to implement all methods, because the Protocol super-class already provides implementations of all the methods on IProtocol . 这种情况下,你并不需要实现所有的方法,因为Protocol的超类已经提供了对所有方法的实现IProtocol In general, Twisted provides a superclass that has default or empty versions of all the methods for many of the more frequently-used interfaces that Twisted application developers must implement. 通常,Twisted提供了一个超类,该类具有Twisted应用程序开发人员必须实现的许多更常用接口的所有方法的默认版本或空版本。

I'm not quite sure what you're asking, too. 我也不太确定您要问什么。

IMO, reaching github for their source code is the fastest way to learn. IMO,获取github的源代码是最快的学习方法。 As you can see, there are default implementation for startedConnecting and clientConnectionLost (empty code, though). 如您所见, startedConnectingclientConnectionLost (不过为空代码)具有默认实现。

Therefore, you just need to implement callbacks you need but not all methods defined in that interface. 因此,您只需要实现所需的回调,而无需实现该接口中定义的所有方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM