1

我需要使用 super 将 kwarg 传递给相当于 FingerFactoryFromService 的父类。

我知道我实际上是将 kwarg 传递给 IFingerFactory 因为这也是我传递最终在init FingerFactoryFromService 中的服务的地方,我可以理解它在组件系统的某个地方被绊倒了,但我想不出任何其他方式。

我不断收到的错误是

exceptions.TypeError: 'test' is an invalid keyword argument for this function

我的 virtualenv 中的代码版本是:

pip (1.4.1)
setuptools (1.1.6)
Twisted (13.1.0)
wsgiref (0.1.2)
zope.interface (4.0.5)

这是手指教程中演示该问题的缩减示例:

from twisted.protocols import basic

from twisted.application import internet, service
from twisted.internet import protocol, reactor, defer
from twisted.python import components
from zope.interface import Interface, implements  # @UnresolvedImport


class IFingerService(Interface):

    def getUser(user):  # @NoSelf
        """
        Return a deferred returning a string.
        """

    def getUsers():  # @NoSelf
        """
        Return a deferred returning a list of strings.
        """


class IFingerFactory(Interface):

    def getUser(user):  # @NoSelf
        """
        Return a deferred returning a string.
        """

    def buildProtocol(addr):  # @NoSelf
        """
        Return a protocol returning a string.
        """


def catchError(err):
    return "Internal error in server"


class FingerProtocol(basic.LineReceiver):

    def lineReceived(self, user):
        d = self.factory.getUser(user)
        d.addErrback(catchError)

        def writeValue(value):
            self.transport.write(value + '\r\n')
            self.transport.loseConnection()
        d.addCallback(writeValue)


class FingerService(service.Service):

    implements(IFingerService)

    def __init__(self, filename):
        self.filename = filename
        self.users = {}

    def _read(self):
        self.users.clear()
        for line in file(self.filename):
            user, status = line.split(':', 1)
            user = user.strip()
            status = status.strip()
            self.users[user] = status
        self.call = reactor.callLater(30, self._read)  # @UndefinedVariable

    def getUser(self, user):
        print user
        return defer.succeed(self.users.get(user, "No such user"))

    def getUsers(self):
        return defer.succeed(self.users.keys())

    def startService(self):
        self._read()
        service.Service.startService(self)

    def stopService(self):
        service.Service.stopService(self)
        self.call.cancel()


class FingerFactoryFromService(protocol.ServerFactory):

    implements(IFingerFactory)

    protocol = FingerProtocol

    #def __init__(self, srv):
    def __init__(self, srv, test=None):
        self.service = srv
        ## I need to call super here because my equivalent of ServerFactory requires 
        ## a kwarg but this cutdown example doesnt so I just assign it to a property
        # super(FingerFactoryFromService, self).__init__(test=test)
        self.test_thing = test or 'Default Something'

    def getUser(self, user):
        return self.service.getUser(user)

components.registerAdapter(FingerFactoryFromService,
                           IFingerService,
                           IFingerFactory)

application = service.Application('finger')
serviceCollection = service.IServiceCollection(application)

finger_service = FingerService('/etc/passwd')
finger_service.setServiceParent(serviceCollection)

#line_finger_factory = IFingerFactory(finger_service)
line_finger_factory = IFingerFactory(finger_service, test='Something')
line_finger_server = internet.TCPServer(1079, line_finger_factory)
line_finger_server.setServiceParent(serviceCollection)  
4

1 回答 1

1

这与组件系统无关。您想要做的是覆盖工厂的 buildProtocol 方法,如此处所述:

https://twistedmatrix.com/documents/current/core/howto/servers.html#auto9

于 2013-10-02T01:19:44.353 回答